it-swarm-tr.com

Git'te bırakılan bir zula nasıl kurtarılır?

Çalışma ağacımdaki değişiklikleri kaydedip geri yüklemek için sık sık git stash ve git stash pop kullanıyorum. Dün, çalışma ağacımda sakladığım ve fırlattığım bazı değişiklikler oldu ve sonra çalışma ağacımda daha fazla değişiklik yaptım. Geri dönüp dünkü aşamalı değişiklikleri gözden geçirmek istiyorum, ancak ilişkili taahhütle ilgili tüm referansları silmek için git stash pop görünmektedir.

git stash kullanırsam, .git/refs/stash içerir stash'ı oluşturmak için kullanılan taahhüdün referansını biliyorum. Ve .git/logs/refs/stash içerir bütün stash. Ancak bu referanslar git stash pop 'dan sonra gider. Taahhüdün hala bir yerlerde depoda olduğunu biliyorum, ama ne olduğunu bilmiyorum.

Dünkü sadakat referansını kurtarmanın kolay bir yolu var mı?

Bunun bugün benim için kritik olmadığına dikkat edin, çünkü günlük yedeklemelerim var ve dünkü çalışma ağacına değişiklikleri alabilirim. Soruyorum çünkü daha kolay bir yol olmalı!

1489
Greg Hewgill

Bıraktığın zırvaya karıştığını öğrendikten sonra, onu zula olarak uygulayabilirsin:

git stash apply $stash_hash

Veya bunun için ayrı bir dal oluşturabilirsiniz.

git branch recovered $stash_hash

Ondan sonra, normal araçlarla ne istersen yapabilirsin. İşiniz bittiğinde, sadece şubeyi uçurun.

Karma bulmak

Henüz yeni açtıysanız ve terminal hala açıksa, yine de ekranda git stash pop ile basılan karma değere sahip olacaksınızteşekkürler, Dolda) olacaktır.

Aksi takdirde, bunu Linux, Unix veya Windows için Git Bash kullanarak bulabilirsiniz:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

... veya Windows için Powershell kullanarak:

git fsck --no-reflog | select-string 'dangling commit' | foreach { $bits = $_ -split ' '; echo $bits[2];}

Bu, artık herhangi bir daldan veya etiketten referans alınmayan taahhüt grafiğinizin ipuçlarındaki tüm taahhütleri gösterir - oluşturduğunuz her zekâ taahhüdü de dahil olmak üzere her kaybedilen iş o grafikte bir yerde olur.

İstediğiniz stash taahhüdünü bulmanın en kolay yolu muhtemelen bu listeyi gitk dizinine aktarmaktır:

gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

... veya Windows için Powershell kullanıyorsanız, sınırların yanıtı bölümüne bakın.

Bu size _'i gösteren bir depo tarayıcıyı başlatır (_ ulaşılabilir olup olmamasına bakılmaksızın, havuzdaki her iş,).

Konsolda ayrı bir GUI uygulaması üzerinde güzel bir grafik tercih ederseniz, gitk orada git log --graph --oneline --decorate gibi bir şeyle değiştirebilirsiniz.

Stash taahhütlerini tespit etmek için şu formdaki taahhüt mesajlarını arayın:

Üzerinde WIP somebranchcommithash Bazı eski taahhüt mesajı

Note: Onay mesajı, git stash yaptığınız zaman bir mesaj vermediyseniz, yalnızca bu formda ("WIP açık" ile başlayarak) olacaktır.

2402

Eğer terminali kapatmadıysanız, çıktıya git stash pop dosyasından bakın, bırakılan stash'ın nesne kimliğine sahip olacaksınız. Normalde şöyle görünür:

$ git stash pop
[...]
Dropped refs/[email protected]{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)

(git stash drop da aynı satırı ürettiğini unutmayın.)

Bu zırvaları geri almak için, sadece git branch tmp 2cae03e komutunu çalıştırmanız yeterli. Şube olarak alırsınız. Bunu bir batağa dönüştürmek için şunu çalıştırın:

git stash apply tmp
git stash

Bir dal olarak bulundurmak, onu serbestçe değiştirmenizi sağlar; örneğin, vişne seçmek veya birleştirmek için.

664
Dolda2000

Sadece kabul edilen çözüme bu ilaveden bahsetmek istedim. Bu yöntemi ilk kez denediğimde (belki de olması gerekirdi) hemen belli değildi, ama hash değerinden zulalamayı uygulamak için, sadece "git stash Uygula" kullanın:

$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219

Git'te yeniyken, bu benim için net değildi ve "git show", "git application", "patch" gibi farklı kombinasyonlar deniyordum.

252
Wade

Hala deponuzda bulunan ancak daha fazla erişilemeyen eşyaların listesini almak için:

git fsck --unreachable | grep commit | cut -d" " -f3 | xargs git log --merges --no-walk --grep=WIP

Stashınıza bir başlık verdiyseniz, komutun sonunda -grep=WIP içindeki "WIP" ifadesini mesajınızın bir parçasıyla değiştirin; -grep=Tesselation.

Komut "WIP" için hitap ediyor çünkü bir stash için varsayılan onay mesajı WIP on mybranch: [previous-commit-hash] Message of the previous commit. biçiminde.

79
Senthil A Kumar

Kayıp eşya işimi bulmama yardım eden bir komut yaptım:

for ref in `find .git/objects | sed -e 's#.git/objects/##' | grep / | tr -d /`; do if [ `git cat-file -t $ref` = "commit" ]; then git show --summary $ref; fi; done | less

Bu, .git/objects ağacındaki tüm nesneleri listeler, tür işleme yapanları bulur, ardından her birinin bir özetini gösterir. Bu noktadan itibaren, uygun bir "İş WIP: 6a9bb2" (“iş” benim şubemdir, 619bb2 yeni bir işlemdir) bulmak için taahhütlere bakmaktan ibaretti.

"Git stash pop" yerine "git stash application" kullanırsam bu sorunu yaşamayacağımı ve "git stash save message " kullanırsam o zaman taahhüdümün daha kolay olabileceğini unutmayın.

Güncelleme: Nathan'ın fikriyle, bu kısalır:

for ref in `git fsck --unreachable | grep commit | cut -d' ' -f3`; do git show --summary $ref; done | less
71
Greg Hewgill

git fsck --unreachable | grep commit sha1 değerini göstermelidir, ancak döndürdüğü liste oldukça büyük olabilir. git show <sha1>, istediğiniz taahhüt olup olmadığını gösterecektir.

git cherry-pick -m 1 <sha1>, varolan daldaki taahhüdü birleştirir.

38
Nathan Jones

Kayıp bir eşyayı yeniden başlatmak istiyorsanız, önce kaybolan malınızın karmasını bulmanız gerekir.

Aristo'nun Pagaltzis'in önerdiği gibi bir git fsck size yardımcı olmalıdır.

Şahsen durumu daha iyi görebilmem için bana her taahhüdüm (kurtarılabilir taahhütler) gösteren log-all takma adımı kullanıyorum:

git log --graph --decorate --pretty=oneline --abbrev-commit --all $(git fsck --no-reflogs | grep commit | cut -d' ' -f3)

Yalnızca "WIP açık" mesajlarını arıyorsanız daha hızlı bir arama yapabilirsiniz.

Sha1'inizi öğrendikten sonra, eski stash'ı eklemek için stash reflog'unuzu değiştirirsiniz:

git update-ref refs/stash ed6721d

Muhtemelen bir mesaj iletmeyi tercih edersiniz, bu yüzden bir -m

git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721d

Hatta bunu takma ad olarak kullanmak isteyeceksiniz:

restash = !git update-ref -m $(git log -1 --pretty=format:'%s' $1) refs/stash $1
27
Colin Hebert

Gitk kullanarak Windows PowerShell eşdeğeri:

gitk --all $(git fsck --no-reflog | Select-String "(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })

Muhtemelen bunu tek bir boruda yapmanın daha etkili bir yolu vardır, ancak bu işi yapar.

19
emragins

Aristoteles'in yaklaşımını beğendim ancak GITK'yi komut satırından GIT kullanmaya alışkın olduğum için kullanmaktan hoşlanmadım.

Bunun yerine, sarkan komisyonları kabul ettim ve kodu kod editörümde gözden geçirmek için bir DIFF dosyasına verdim.

git show $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' ) > ~/stash_recovery.diff

Şimdi ortaya çıkan diff/txt dosyasını (ana klasörünüzde) txt editörünüze yükleyebilir ve gerçek kodu ve sonuçta elde edilen SHA'yı görebilirsiniz.

O zaman sadece kullan

git stash apply ad38abbf76e26c803b27a6079348192d32f52219
16
Shaheen Ghiassy

Git v2.6.4 ile OSX'te, sadece yanlışlıkla git stash drop'ını çalıştırdım, sonra adımların altında ilerleyerek buldum

Zulağın adını biliyorsanız o zaman kullanın:

$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show | grep -B 6 -A 2 <name of the stash>

aksi takdirde sonuçtaki kimliği elle ile bulabilirsiniz:

$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show

Ardından, kullanıcı kimliğini bulduğunuzda git git stash komutuna basın. {Commit-id}

Umarım bu çabuk birine yardımcı olur

12
Can Tecim

İnsanlar neden bu soruyu soruyor? Çünkü reflog hakkında henüz bir şey bilmiyorlar ya da anlamıyorlar.

Bu sorunun çoğu cevabı neredeyse hiç kimsenin hatırlayamayacağı seçeneklerle uzun komutlar veriyor. Böylece insanlar bu soruya giriyorlar ve ihtiyaç duydukları her şeyi kopyalayıp yapıştırıyor ve hemen ardından unutuyorlar.

Bu soruyu herkese sadece daha fazla değil, sadece reflog (git reflog) kontrol etmelerini öneririm. Tüm taahhütlerin listesini gördüğünüzde, aradığınızı bulmanın ve onu seçmenin veya ondan bir dal oluşturmanın yüzlerce yolu vardır. Bu süreçte, çeşitli temel git komutlarının reflog ve faydalı seçeneklerini öğrenmiş olacaksınız.

11
RobbyD

Kabul edilen çözüme, çıktı için gitk veya X'in olmadığı durumlarda tüm değişikliklerin üzerinden geçmek için iyi bir yol eklemek istiyorum.

git fsck --no-reflog | awk '/dangling commit/ {print $3}' > tmp_commits

for h in `cat tmp_commits`; do git show $h | less; done

Ardından, birbiri ardına gösterilen karma değerler için tüm farkları elde edersiniz. Bir sonraki farka geçmek için 'q' tuşuna basın.

10
Phil

Windows üzerinde çalışacak cevapların hiçbirini basit bir komut penceresinde bulamadım (benim durumumda Windows 7). awk, grep ve Select-string komut olarak tanınmadı. Bu yüzden farklı bir yaklaşım denedim:

  • ilk çalıştırma: git fsck --unreachable | findstr "commit"
  • çıktıyı not defterine kopyala
  • start cmd /k git show ile değiştirilemiyor "erişilemez

böyle bir şey görünecek:

start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4 start cmd /k git show 44078733e1b36962571019126243782421fcd8ae start cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1 start cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e

  • bir .bat dosyası olarak kaydedin ve çalıştırın
  • komut dosyası, her bir işlemi gösteren bir sürü komut penceresi açar
  • aradığınızı bulduysanız, run: git stash apply (your hash)

en iyi çözüm olmayabilir, ama benim için çalıştı

9
kromakollision

Bu komutu terminalin içine yazarak erişilemeyen tüm taahhütleri listeleyebilirsiniz -

git fsck --unreachable

Ulaşılamaz kargaşayı kontrol et -

git show hash

Stashed ürününü bulursanız son olarak uygulayın -

git stash apply hash
9
Vivek Kumar

Aristoteles tarafından kabul edilen cevap, zahmetsiz benzeri taahhütler de dahil olmak üzere tüm erişilebilir taahhütleri gösterecektir. Gürültüyü filtrelemek için:

git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3

Bu, yalnızca tam olarak 3 ebeveyn taahhüdüne sahip (bir zulaya sahip olacak) ve mesajı "WIP açık" içeren taahhütleri içerecektir.

Stash'ınızı bir mesajla (ör. git stash save "My newly created stash") kaydettiyseniz, bunun varsayılan "WIP açık ..." mesajını geçersiz kılacağını unutmayın.

Her bir işlemle ilgili daha fazla bilgi görüntüleyebilirsiniz, örn. taahhüt mesajını görüntüle veya git stash show 'a ilet:

git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3 | \
xargs -n1 -I '{}' bash -c "\
  git log -1 --format=medium --color=always '{}'; echo; \
  git stash show --color=always '{}'; echo; echo" | \
less -R
9
Brad Feehan

Aşağıdaki adımları kullanarak kurtardı:

  1. Silinen stash karma kodunu tanımlayın:

    gitk --all $ (git fsck --no-reflog | awk '/ sarkan bir şey/{print $ 3}')

  2. Kiraz Ezmesi Seç:

    git cherry-pick -m 1 $ Instagram Hesabındaki Resim ve Videoları stash_hash_code

  3. Varsa, Çatışmaları çözün:

    git Mergetool

Ek olarak, gerrit kullanıyorsanız taahhüt mesajı ile ilgili sorunlar yaşıyor olabilirsiniz. Lütfen sonraki alternatifleri izlemeden önce değişikliklerinizi saklayın:

  1. Önceki işleme onaylamak için sert sıfırlamayı kullanın ve ardından bu değişikliği tekrar isteyin.
  2. Ayrıca değişikliği saklayabilir, yeniden yapılandırabilir ve tavsiye edebilirsiniz.
4
Abhijeet

Buraya aramaya geldiğim şey, ne kontrol ettiğime bakılmaksızın, gerçekte nasıl saklanacağımı. Özellikle, bir şeyi saklamıştım, daha sonra eski bir sürümü kontrol ettim, sonra fırlattım, ama zırh daha önceki bir zaman diliminde kullanılmıyordu, bu yüzden zırh kayboldu; Sadece yığına geri itmek için git stash yapamadı. Bu benim için çalıştı:

$ git checkout somethingOld
$ git stash pop
...
nothing added to commit but untracked files present (use "git add" to track)
Dropped refs/[email protected]{0} (27f6bd8ba3c4a34f134e12fe69bf69c192f71179)
$ git checkout 27f6bd8ba3c
$ git reset HEAD^    # Make the working tree differ from the parent.
$ git stash # Put the stash back in the stack.
Saved working directory and index state WIP on (no branch): c2be516 Some message.
HEAD is now at c2be516 Some message.
$ git checkout somethingOld # Now we are back where we were.

Geçmişe bakıldığında, git stash apply değil, git stash pop kullanıyor olmalıydım. bisect yapıyordum ve her bisect adımda uygulamak istediğim küçük bir düzeltme eki vardı. Şimdi bunu yapıyorum:

$ git reset --hard; git bisect good; git stash apply
$ # Run tests
$ git reset --hard; git bisect bad; git stash apply
etc.
4
Ben

Benim favorim bu tek gömlek:

git log --oneline  $( git fsck --no-reflogs | awk '/dangling commit/ {print $3}' )

Bu, temelde, bu cevapla aynı fikirdir ancak daha kısadır. Tabii ki, ağaç benzeri bir görüntü elde etmek için hala --graph ekleyebilirsiniz.

Listedeki taahhüdü bulduğunuzda,

git stash apply THE_COMMIT_HASH_FOUND

Benim için, --no-reflogs kullanmak, kayıp stash girişini ortaya çıkardı, ancak --unreachable (diğer birçok cevabın içinde bulunduğu gibi) olmadı.

Windows altındayken git bash'de çalıştırın.

Krediler: Yukarıdaki komutların detayları https://Gist.github.com/joseluisq/7f0f1402f05c45bac10814a9e38f81bf 'den alınmıştır.

1
Adrian W