Git çekme nasıl ödevimi yedi?


53

Müdürün ofisinde, köpeğin doğduğu gün ev ödevimi yediğini açıklayan bir çocuk gibi hissediyorum, ama karşısında çılgınca bir veri kaybı hatası görüyorum ve bunun nasıl olduğunu çözemiyorum. Git'in depo bütünümü nasıl yiyebildiğini bilmek istiyorum! Goring'çiyi defalarca geçirdim ve hiçbir zaman göz kırpmadı. Bir 20 Gig Subversion repoyu 27 git repo'ya bölmek için kullandım ve pisliği çözmek için foo'yu filtre dallandı ve benden asla bir bayt kaybetmedi. Reflog her zaman geri çekilmek için orada. Bu sefer halı gitti!

Benim bakış açıma göre tüm yaptığım koşmak git pullve tüm yerel depolarımı taramaktı. Yani "teslim alınan versiyonu berbat ettin" ya da "bulunduğum dal" lafını kastetmiyorum. Yani her şey bitti .

İşte olaydaki terminalimin ekran görüntüsü:

olay ekran görüntüsü

Sana bu konuda yol göstereyim. Komut istemim, geçerli git repo (prezto'nun vcs_info uygulamasını kullanarak) hakkındaki verileri içerir, böylece git repo'nun ne zaman kaybolduğunu görebilirsiniz. İlk komut yeterince normal:

  » caleb » jaguar » ~/p/w/incil.info » ◼  zend ★ »
❯❯❯ git co master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

Orada 'zend' dalında olduğumu ve ustayı kontrol ettiğimi görebilirsiniz. Çok uzak çok iyi. Bir sonraki komutumdan önce bilgi istemi içinde dalları başarıyla değiştirdiğini göreceksiniz:

  » caleb » jaguar » ~/p/w/incil.info » ◼  master ★ »
❯❯❯ git pull
remote: Counting objects: 37, done.
remote: Compressing objects: 100% (37/37), done.
remote: Total 37 (delta 25), reused 0 (delta 0)
Unpacking objects: 100% (37/37), done.
From gitlab.alerque.com:ipk/incil.info
 + 7412a21...eca4d26 master     -> origin/master  (forced update)
   f03fa5d..c8ea00b  devel      -> origin/devel
 + 2af282c...009b8ec verse-spinner -> origin/verse-spinner  (forced update)
First, rewinding head to replay your work on top of it...
>>> elapsed time 11s

Ve aynen böyle gitti. Geçen süre işaretçisi, 10 saniyeden uzun bir süre geçmişse bir sonraki komut isteminden önce çıkar. Git, tekrar oynatmanın geri sarıldığına dair bir bildirimde bulunmadı. Bittiğine dair bir gösterge yok.

Bir sonraki bilgi istemi, hangi şubede bulunduğumuz veya gitme durumu hakkında hiçbir veri içermiyor.

Başarısız olduğunu fark etmeden, kesinlikle bir git deposunda olmadığımı söylemek için başka bir git komutu çalıştırmaya çalıştım. PWD'nin değişmediğine dikkat edin:

  » caleb » jaguar » ~/p/w/incil.info »
❯❯❯ git fetch --all
fatal: Not a git repository (or any parent up to mount point /home)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

Bundan sonra etrafa bir bakış tamamen boş bir dizinde olduğumu gösterdi. Hiçbir şey değil. '.Git' dizini yok, hiçbir şey yok. Boş.

Benim yerel git 2.0.2 sürümünde. Git yapılandırmamdan olanları yapmak için uygun olabilecek birkaç ipucu:

[branch]
        autosetuprebase = always
        rebase = preserve
[pull]
        rebase = true
[rebase]
        autosquash = true
        autostash = true
[alias]
        co = checkout

Örneğin git pull, bir birleştirme yerine her zaman bir yeniden düzenleme yapmaya ayarlıyorum, böylece yukarıdaki çıktının bir kısmı normal olur.

Verileri kurtarabilirim. Diğer depolara itilmemiş, önemsiz bazı şeyler dışında başka git objeleri olduğunu sanmıyorum, ama ne olduğunu bilmek istiyorum .

Kontrol ettim:

  • Dmesg'deki veya sistem günlüğündeki mesajlar. Hiçbir şey uzaktan bile alakalı değil.
  • Sürücü veya dosya sistemi arızası belirtisi yok (LVM + LUKS + EXT4 hepsi normal görünüyor). Kayıp + bulunan hiçbir şey yok.
  • Ben başka bir şey yapmadım. Tarihte yukarıda göstermediğim hiçbir şey yok ve bu süre zarfında başka terminal kullanılmadı. rmYanlış CWD, vb. İçerisinde yürütülmüş olabilecek yüzen bir komut yoktur .
  • Başka bir dizindeki başka bir git repouna göz atmak, git pulls'yi çalıştıran hiçbir belirgin anormallik göstermez .

Burada başka ne aramalıyım?


4
@Patrick Zaten soruda açıkladığım gibi, hiç .gityok. Hiçbir şey yapmaz - git root dizini olarak kullanılanların içinde hiçbir şey yoktur.
Caleb

2
@Alexander Çekme işlemi normaldir (başka bir birleştirme yerine yeniden yapılanma). Zorla yapılan bir güncelleme ile ilgili uyarı, çektiğim reponun, yerel reponun gördüğü yerden farklı bir konumdan sıfırlayan bir zorlamaya neden olduğunu gösteriyor. Bu normal bir durumdur çünkü diğer geliştiricilerin göreceği bir kamu dalı değil aktif olarak geliştirilen ve sık sık yeniden doğmuş materyalleri kendi bilgisayarlarım arasında senkronize ediyorum.
Caleb

3
@Caleb sizin kabuk istemi git dal göstergesi içerir, bu PS1'i oluşturan günlüğünde açığa git git git komutları içeren anlamına gelir. Prensip olarak resmi değiştirebilirler ve konu kaynağı olabilirler. Kabuk isteminizin nasıl oluştuğunu, mevcut bir şubeye ulaşmak için hangi komutların uygulandığını açıklayan soruyu güncellemeli ve deponuzu nasıl bozabileceklerini yeniden düşünmelisiniz.

2
@Caleb Gerçekten git geliştirme e-posta listesinde sormalısınız; Bunu bir hata raporu olarak yazabilir ya da sadece gayri resmi olarak sorabilirsiniz - yine de aynı. Git'i etkileyici bir şekilde iyi bilen bazı geliştiriciler var - muhtemelen ne olduğunu sezgiyle anlatabilirler. (Olmazsa, tartışmayı sessizce takip edeceklerdir.) Daha önce olup olmadığını da biliyorlar. (Bunu bildirmek, git için hataları rapor etmenin "resmi" bir yolu var)
Volker Siegel

7
@Wildcard Aslında, ne olduğunu çözdüğümde buna bir cevap vermek istedim. Sistem yakın zamanda uykudan kalkmıştı ve ağ uykuya dalmadan önce günlerce dışarıda kalmıştı. Bu süreçte bir yerde, sistemdeki bir şeyi yükseltmeye çalışan bir pacman işlemi bıraktım. Uzun lafın kısası, glibc'in güncellendiği ve git ikili yazısının üzerine yazıldığı ortaya çıktı. Kendi kendini çatallama şekli nedeniyle, bir örnek diğerinden farklıydı ve birbirlerinin öğle yemeğini yediler. Dizin gerçekten boştu (sadece görünen şey değil
Caleb

Yanıtlar:


6

Evet gitödevimi yedim. Hepsini.

ddOlaydan sonra bu diskin bir görüntüsünü aldım ve daha sonra onunla uğraştım. Olayları sistem günlüklerinden yeniden yapılandırarak, olanların şu şekilde olduğunu anlıyorum:

  1. pacman -SyuBu olaydan birkaç gün önce bir sistem güncelleme komutu ( ) verildi.
  2. Genişletilmiş bir ağ kesintisi, paketleri indirmeyi denemeye devam ettiği anlamına geliyordu. İnternet eksikliğinde sinirli, sistemi uyutup yatağa yatırdım.
  3. Günler sonra sistem uyandı ve paketleri tekrar bulmaya ve indirmeye başladı.
  4. Paket indirme işlemi, bir süre önce bu depo ile uğraşmadan önce bitti.
  5. Sistem glibc kurulumu, git checkoutöncesi ve sonrası olarak güncellenmiştir git pull.
  6. gitSonra ikili yerine var git pullbaşladı ve bitirdi önce.
  7. Ve yedinci günde, gittüm emeklerinden dinlendi. Ve dünyayı sildim böylece herkes dinlenmek zorunda kaldı.

Bunun gerçekleşmesini sağlayan hangi yarış koşulunun tam olarak olduğunu bilmiyorum , ancak bir işlemin ortasında ikilileri çıkarmak kesinlikle iyi değil ya da test edilebilir / tekrarlanabilir bir durumdur. Genellikle çalışan bir ikili dosyanın bir kopyası hafızada saklanır, ancak gitgariptir ve kendisinin versiyonlarını yeniden ortaya çıkarmasıyla ilgili bir şey budur. Açıkçası her şeyi mahvetmek yerine ölmüş olmalıydı, ama olan buydu.


1
git başarısız olmuş olabilir çünkü git farklı komutları kullanarak, tek bir ikili komut kullanır. Basit bir git çekme çalıştırır git-fetch, git-rebaseya da git-mergevegit gc
Ferrybig

2

Muhtemelen silinecek dosya yolunu tanımlamakta başarısızlıkla.

Davanız bana güzel bir gün hatırlattı, çünkü ev yapımı remove(path)yöntemim kök klasörü kaldırmaya çalıştığında verilen parametre boş dizgeydi çünkü işletim sistemi kök klasör olarak düzeltildi (!).

Bu benzer bir git böcek olabilir. Öyle ki:

  1. Rebase komutu gibi bir dosyayı silmek istedi remove(project_folder + file_path)(sözde kod)
  2. O sırada bir şekilde file_pathboştu.
  3. Komuta gibi bir şey olarak değerlendirildi remove(project_folder)

1

Şansınız varsa, aşağıdaki komutu kullanarak bunu düzeltebilirsiniz:

git reset --hard ORIG_HEAD  

Potansiyel tehlikeli değişiklikler başladığında, git geçerli durumunuzu ORIG_HEAD içinde saklar. Bununla beraber bir birleştirme veya rebase geri alabilirsiniz.

Git Kılavuzu: Bir Birleştirmeyi Geri Alma


4
Tüm soruyu okuduğunu sanmıyorum. Bu tür bir düzeltme tamamen söz konusu değil, çünkü git meta-veri yok . Bunun gibi bir sıfırlama yapmak, mevcut bir .git dizini ve üzerinde çalışacak bazı nesneler gerektirir. Hiçbir şeyim yok. Bu sadece karışık bir çalışma dizini değil, artık her türlü bir depo değil.
Caleb,

Ahh, özür dilerim. Bu çok sıradışı. Git repo gitti ise, Linux'ta dosyaları gölgelendirmediğiniz ve fs yedeklerini almadığınız sürece kurtarmanın bir yolu olmayacağını varsayalım. Cevabımı alakasız olduğu için sileceğim.
Routhinator

Evet, bunun olağandışı bir sorun olduğunu biliyorum (ve yedeklerim var). Buradaki sorum, nasıl yanlış gittiği ... git veya dosya sistemi sürücümdeki hatayı nerede arayacağımı ya da böyle bir işlemin ortasında bir dizin yemek için başka ne olabilirdi.
Caleb,

Ben de çok merak ediyorum. Depolarıma böyle bir şeyin gelmesi için nefret ediyorum.
Routhinator

-1

Görünüşe göre birisi git push --forcebu depoya girdi ve siz de bu değişiklikleri yaptınız. Repoyu taze klonlamayı deneyin, bu sizi tekrar temiz bir çalışma durumuna sokmalıdır.


1
Zorla basma işlemi, son avukatlık komisyonunu yeniden açtı. Aşağıya çektiğim şey bu değildi (çalışma dizini artık bir çalışma dizini değil!) Ve yeniden klonlamak bile bir anlam ifade etmiyordu.
Caleb

4
.gitZorla basma ile birisinin dizinini kaldırabileceğinizi sanmıyorum
Grzegorz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.