Git'te kaybedilen bir taahhüdü nasıl kurtarabilirim?


Yanıtlar:


589

git reflogsenin arkadaşın. Listede bulunmasını istediğiniz taahhüdü bulun ve sıfırlayabilirsiniz (örneğin:) git reset --hard e870e41.

(Değişikliklerinizi yapmadıysanız ... başınız belada olabilir - erken ve sık sık taahhüt edin!)


5
Bir göz atın git log HEAD@{1}. Bu doğru taahhüt dizisine benziyorsa, yapabilirsiniz git reset HEAD@{1}.
Amber

4
Yalnızca kodlar aşamalanırsa (git add kullanarak), git içinde tutulur ve gibi komutlar kullanılarak kolayca bulunabilir git fsck --lost-found.
Landys

2
Yeniden basarken saklamam gereken bir taahhüdü yanlışlıkla düşürdüm. Bu beni birkaç saatlik çalışmayla tekrar etmekten kurtardı.
josephting

27
Bu hayatımı kurtardı.
Lutaaya Huzaifah Idris

6
Bu benim aklıma kurtardı: D
Frank Fajardo

120

Yanıtlamadan önce bunun ne HEADolduğunu açıklayan bir arka plan ekleyelim .

First of all what is HEAD?

HEADyalnızca geçerli daldaki geçerli taahhüde (en son) bir referanstır. Herhangi bir zamanda
yalnızca bir kişi olabilir HEAD(hariç git worktree).

İçeriği HEADiçeride saklanır .git/HEADve mevcut taahhüdün 40 bayt SHA-1'ini içerir.


detached HEAD

En son taahhütte değilseniz - yani HEADtarihte önceki bir taahhüde işaret eden anlamına gelir detached HEAD.

Resim açıklamasını buraya girin

Komut satırında, HEADşu anki dalın ucunu işaret etmediğinden , şube adı yerine SHA-1 şöyle görünecektir :

Resim açıklamasını buraya girin

Resim açıklamasını buraya girin


Müstakil bir KAFADAN kurtarma için birkaç seçenek:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Bu, istenen taahhüde işaret eden yeni şubeyi kontrol edecektir.
Bu komut, verilen bir taahhüde ödeme yapar.
Bu noktada, bir şube oluşturabilir ve bu noktadan itibaren çalışmaya başlayabilirsiniz.

# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# Create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Her zaman da kullanabilirsiniz reflog.
git reflog güncellenen değişiklikleri görüntüleyecek HEADve istenen reflog girişini kontrol HEADetmek bu işleme geri dönecektir.

HEAD her değiştirilişinde, reflog

git reflog
git checkout HEAD@{...}

Bu sizi istediğiniz taahhüde geri götürür

Resim açıklamasını buraya girin


git reset --hard <commit_id>

HEAD'inizi istenen işleme geri "taşıyın".

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.

git revert <sha-1>

Verilen taahhüt veya taahhüt aralığını "Geri al".
Sıfırlama komutu, verilen işlemde yapılan değişiklikleri "geri alır".
Geri alma yamasıyla yeni bir taahhüt gerçekleştirilecek, orijinal taahhüt de tarihte kalacaktır.

# Add a new commit with the undo of the original one.
# The <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Bu şema hangi komutun ne yaptığını gösterir.
Orada görebileceğiniz gibi, reset && checkoutmodifiye HEAD.

Resim açıklamasını buraya girin


2
Sen bir kahramansın, efendim
dylanh724

4
Bu da beni saatler süren işten kurtardı. Zaman damgası olmadan emin olamadım çünkü "git reflog --date = iso" her giriş için tarih / saat görmek için kullanılır.
MetalMikester

1
benim için, içinde git reset --hard <commit_id>, kaldırma HEADçalıştı! Grafik gösterim için +1 !!.
reverie_ss

Şunu git reflog <branchname>söylemek gerekirse: şube adını biliyorsanız: sadece bir dalın değişikliklerini gördüğünüz için oldukça yararlı olabilir.
Markus Schreiber

35

Silinen taahhüde ulaşmanın başka bir yolu da git fsckkomuttur.

git fsck --lost-found

Bu, son satırdaki gibi bir şey çıktılar:

dangling commit xyz

reflogDiğer cevaplarda önerilenlerle aynı işlem olup olmadığını kontrol edebiliriz . Şimdi birgit merge

git merge xyz

Not: Sarkan işleme referansı kaldıracak bir komutu zaten çalıştırdıysak
taahhüdü geri alamayız.fsckgit gc


3
Bu, yakın zamanda söz konusu taahhüdü işaret etmediyseniz, örneğin bir şube getirdiğinizde ve daha sonra bu dalı başka bir yerde yanlışlıkla sıfırladığınızda işe yarayan tek yanıttır.
TamaMcGlinn
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.