Git'teki en son yerel taahhütleri nasıl geri alabilirim?


21057

Yanlışlıkla Git'e yanlış dosyalar verdim, ancak taahhüdü henüz sunucuya aktarmadım.

Bu taahhütleri yerel depodan nasıl geri alabilirim?


138
Yeni bir yanıt göndermeden önce, bu soru için zaten 65'ten fazla yanıt olduğunu düşünün. Cevabınızın mevcut cevaplar arasında olmayanları katkıda bulunduğundan emin olun.
Sazzad Hissain Khan

89
Git'in neye ihtiyacı olduğunu biliyor musun? git undo, bu kadar. O zaman git git bizim tarafımızdan yapılan hataların ele alınması için var, sadece ölümlüler yok oluyor. Herhangi bir gitkomutu yürütmeden önce geçerli durumu git yığınının üzerine iterek uygulayın . Performansı etkiler, bu nedenle etkinleştirilip etkinleştirilmeyeceği konusunda bir yapılandırma bayrağı eklemek en iyisidir.
Yimin Rong

11
@YiminRong Git'in aliasözelliği ile yapılabilir : git-scm.com/book/en/v2/Git-Basics-Git-Aliases
Edric

3
@RomainValeri - Geri alma işlemi başka her yerde de çalışır.
Yimin Rong

1
@YiminRong Satın almıyoruz. İnsanlar hala geri çekilmeyecek ve geri alınmaması gereken şeyleri geri alacaktı. Ancak daha da önemlisi, git reflogzaten tanımladığınız şeye yakındır, ancak kullanıcıya ne yapılacağı (un) üzerinde daha fazla kontrol sağlar. Ama lütfen, hayır, "geri al" her yerde aynı şekilde çalışmaz ve insanlar bu özelliğin başarılması için birçok farklı şey beklerdi . Son işlem geri alınsın mı? Son işlem geri alınsın mı? Son işlem bir itme olsaydı, tam olarak nasıl (sıfırlama ve itme) veya (geri alma ve itme) geri alın?
RomainValeri

Yanıtlar:


22855

Bir taahhüdü geri alma ve yineleme

$ git commit -m "Something terribly misguided"             # (1)
$ git reset HEAD~                                          # (2)
<< edit files as necessary >>                              # (3)
$ git add ...                                              # (4)
$ git commit -c ORIG_HEAD                                  # (5)
  1. Geri almak istediğiniz şey budur.
  2. Bu, çalışma ağacınıza (diskteki dosyalarınızın durumu) hiçbir şey yapmaz, ancak taahhüdü geri alır ve taahhüt ettiğiniz değişiklikleri ayrılmamış bırakır (bu nedenle "Taahhüt için hazırlanmayan değişiklikler" olarak görünürler git status. taahhütte bulunmadan önce tekrar ekleyin). Eğer varsa sadece istediğiniz eklemek önceki daha fazla değişiklik yapmak veya mesaj taahhüt değiştirmek 1 şunu kullanabilirsiniz git reset --soft HEAD~gibi olan yerine git reset HEAD~2 ancak mevcut değişikliklerin aşamalı bırakır.
  3. Çalışan ağaç dosyalarında düzeltmeler yapın.
  4. git add yeni taahhüdünüze dahil etmek istediğiniz her şey.
  5. Eski taahhüt mesajını yeniden kullanarak değişiklikleri uygulayın. resetyaşlı kafayı kopyaladı .git/ORIG_HEAD; commitile -c ORIG_HEADbaşlangıçta eski iletiden gelen günlük iletisini içeren ve düzenlemenizi sağlayan bir düzenleyici açılır. Mesajı düzenlemeniz gerekmiyorsa, -Cseçeneği kullanabilirsiniz .

Bununla birlikte, dizine yeni değişiklikler eklediyseniz, kullanmanın commit --amendbunları önceki taahhüdünüze ekleyeceğini unutmayın.

Kod zaten sunucunuza aktarılmışsa ve geçmişin üzerine yazma (rebase) izinleriniz varsa:

git push origin master --force

Bu yanıta da bakabilirsiniz:

HEAD'ı önceki bir konuma nasıl geri taşıyabilirim? (Ayrılmış kafa) ve Geri alma taahhütleri

Yukarıdaki cevap git reflog,size, geri almak istediğiniz SHA-1'in hangisinin olduğunu bulmak için kullanıldığını gösterecektir . Komut sırasını yukarıda açıklandığı gibi kullanmak için geri almak istediğiniz noktayı bulduğunuzda.


1 Ancak, kaydetme iletinizde bir hata yaptıysanız, daha önceki bir işleme sıfırlamanıza gerek olmadığını unutmayın . Daha kolay seçenek git reset(o zamandan beri yaptığınız değişiklikleri kaldırmak için) ve daha sonra git commit --amend, son tamamlama mesajıyla önceden doldurulmuş varsayılan tamamlama mesajı düzenleyicinizi açacaktır.

2 HEAD~ ile aynıdır HEAD~1. Ayrıca bkz . Git'deki HEAD nedir? . Birden fazla taahhütten vazgeçmek istiyorsanız faydalıdır.


472
Ve taahhüt yanlış şubeye aitse, git checkout theRightBranchtüm değişiklik aşamalarıyla yapabilirsiniz. Sadece yapmak zorunda olduğum gibi.
Frank Shearar

490
DOS'ta çalışıyorsanız bunun yerine git reset --soft HEAD^kullanmanız gerekir git reset --soft HEAD~1. ^, DOS'ta bir devam karakteri olduğundan düzgün çalışmaz. Ayrıca, --softvarsayılan değerdir, bu yüzden isterseniz ve sadece söylerseniz atlayabilirsiniz git reset HEAD~1.
Ryan Lundy

119
zsh kullanıcıları alabilir: zsh: no matches found: HEAD^- kaçmak gerekir ^ iegit reset --soft HEAD\^
tnajdek

7
Kazara, derseniz cevabı doğru değil git commit -ane zaman verildiği -adışarı bırakılmış olması gerekirdi. Bu durumda, --soft( --mixedvarsayılan olan ile sonuçlanacaktır) dışarıda bırakmamak daha iyidir ve daha sonra taahhüt etmek istediğiniz değişiklikleri yeniden düzenleyebilirsiniz.
dmansfield

6
@IcyBrk git add bir komuttur. git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p] [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]] [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--chmod=(+|-)x] [--] [<pathspec>…​]
Ashraf.Shk786

10732

Nasıl çalıştığını bilmiyorsanız, bir taahhüdü geri almak biraz korkutucu. Ama anlarsanız aslında inanılmaz derecede kolaydır.

Diyelim ki C, HEAD'ınız ve (F) dosyalarınızın durumu.

   (F)
A-B-C
    ↑
  master

C komutunu tıklatmak ve bir daha asla görmek ve yerel olarak değiştirilmiş dosyalardaki tüm değişiklikleri kaybetmek istiyorsunuz . Bunu yap:

git reset --hard HEAD~1

Sonuç:

 (F)
A-B
  ↑
master

Şimdi B KAFA. Çünkü kullandın--hard , dosyalarınız işlem B'de durumlarına sıfırlanır.

Ah, ama C taahhüdünün bir felaket olmadığını, ancak biraz uzakta olduğunu varsayalım. Taahhüdü geri almak istiyorsunuz, ancak daha iyi bir taahhütte bulunmadan önce değişikliklerinizi biraz düzenlemek için saklamak istiyorsunuz. Buradan başlayarak, KAFA olarak C ile:

   (F)
A-B-C
    ↑
  master

Bunu, aşağıdakileri bırakarak yapabilirsiniz --hard:

git reset HEAD~1

Bu durumda sonuç:

   (F)
A-B-C
  ↑
master

Her iki durumda da, HEAD en son taahhüdün sadece bir göstergesidir. Yaptığın zamangit reset HEAD~1 Git'e HEAD işaretçisini bir işlem geri götürmesini söylersiniz. Ancak (kullanmadığınız sürece --hard) dosyalarınızı olduğu gibi bırakırsınız. Şimdi git statusC'ye giriş yaptığınız değişiklikleri gösteriyor. Hiç bir şey kaybetmediniz!

En hafif dokunuş için taahhüdünüzü bile geri alabilir, ancak dosyalarınızı ve dizininizi bırakabilirsiniz :

git reset --soft HEAD~1

Bu sadece dosyalarınızı yalnız bırakmakla kalmaz, dizininizi bile yalnız bırakır . Ne zaman yaparsıngit status , aynı dosyaların daha önce olduğu gibi dizinde olduğunu görürsünüz. Aslında, bu komuttan hemen sonra, yapabilirdiniz git commitve az önce yaptığınız aynı taahhüdü yeniden yapardınız .

Bir şey daha var: İlk örnekteki gibi bir taahhüdü yok ettiğinizi varsayalım , ama sonuçta ihtiyacınız olduğunu mu keşfettiniz ? Zor şanslar, değil mi?

Hayır, orada hala geri almanın bir yolu. Yazın git reflogve bir listesini göreceksiniz (kısmi) işlemek Şas sen etrafında hareket ettik (yani, sağlamalarının) siz yok işlemek ve bunu bulun.:

git checkout -b someNewBranchName shaYouDestroyed

Şimdi bu taahhüdü dirilttin. Taahhütler Git'te 90 gün boyunca gerçekten yok edilmez, bu nedenle genellikle geri dönüp kurtulmak istemediğiniz birini kurtarabilirsiniz.


15
DİKKAT! Hatalı taahhüdünüz (hızlı ileri) birleştirme ise, beklediğiniz şeyi yapmayabilir! Kafanız bir birleştirme taahhüdü üzerindeyse (ör: ana dalda birleştirilmiş şube özelliği), git reset --hard~1ana dalı özellik dalındaki son işleme yönlendirir. Bu durumda, göreceli komut yerine belirli bir taahhüt kimliği kullanılmalıdır.
Chris Kerekes

90
Önemli bir noktayı kaçırmak: Söz konusu taahhüt daha önce uzaktan kumandaya 'itilmiş' ise, ne kadar basit olursa olsun, herhangi bir 'geri al' işlemi, yerel kopyalarında bu taahhüde sahip olan diğer kullanıcılara büyük acı ve acı çekecektir, ileride bir 'git pull' yaptıkları zaman. Yani, taahhüt zaten 'itilmiş' ise, bunun yerine bunu yapın: git
revert

12
@FractalSpace, "muazzam acı ve ıstırap" yaratmaz. Git'i bir ekiple kullanırken birkaç kuvvet uyguladım. Tek gereken iletişim.
Ryan Lundy

14
@Kyralessa İşyerimde, tüm ekibin iş akışını bozuyor ve onlara sh * t'yi nasıl düzeltebileceklerini anlatmak 'iletişim' olarak adlandırılmıyor. git history re-write, deponun parçalarının çöpe atılmasına yol açan yıkıcı bir işlemdir. Kullanımında ısrar ederken, açık ve güvenli alternatifler mevcutken sorumsuzdur.
FractalSpace

14
Bir taahhütte bulunmak ve bir daha asla görmek istemedim. --hardÖrneğinizi kullandım ama fark etmediğim şey, çalışma ağacımdaki tüm değişmemiş değişikliklerin de nükleer silahlara büründüğü! Bu dosyaları daha sonraki bir taahhüdün parçası olarak işleyecektim. Şimdi bu dosyaları geri almak imkansız görünüyor - hakkında yayınladığınız çözümü bile denedim, reflogancak bu daha önce değiştirilmemiş değişiklikleri geri yüklemedi.
Adam Burley

2129

Taahhütünüzü daha önce herkese açık hale getirip getirmediğinize (uzak deponuza aktarılmış olarak) bağlı olarak son taahhüdünüzü "geri almanın" iki yolu vardır:

Yerel bir taahhüt nasıl geri alınır

Diyelim ki yerel olarak taahhütte bulundum, ancak şimdi bu taahhüdü kaldırmak istiyorum.

git log
    commit 101: bad commit    # Latest commit. This would be called 'HEAD'.
    commit 100: good commit   # Second to last commit. This is the one we want.

Son öncesinde taahhüt edilmiş şekilde her şeyi geri yüklemek için, gerek resetdaha önce işlemeye HEAD:

git reset --soft HEAD^     # Use --soft if you want to keep your changes
git reset --hard HEAD^     # Use --hard if you don't care about keeping the changes you made

Şimdi git logson taahhüdümüzün kaldırıldığını göstereceğiz.

Bir kamu taahhüdü nasıl geri alınır

Taahhütlerinizi daha önce herkese açık hale getirdiyseniz, önceki taahhüdünüzde (mevcut HEAD) yaptığınız değişiklikleri "geri alacak" yeni bir taahhüt oluşturmak istersiniz.

git revert HEAD

Değişiklikleriniz artık geri alınacak ve taahhütte bulunmaya hazır olacak:

git commit -m 'restoring the file I removed by accident'
git log
    commit 102: restoring the file I removed by accident
    commit 101: removing a file we don't need
    commit 100: adding a file that we need

Daha fazla bilgi için Git Temel Bilgileri - Şeyleri Geri Alma konusuna bakın .


101
Bu cevabı en açık buldum. git revert HEAD^önceki değil, önceki öncekidir. git revert HEAD
Yaptım

Git sizden "Daha fazla?" bu komutları denediğinizde, bu yanıttaki alternatif sözdizimini kullanın: stackoverflow.com/a/14204318/823470
tar

1745

İşleri istediğiniz gibi almak için dosya ekleyin / kaldırın:

git rm classdir
git add sourcedir

Sonra taahhüdü değiştirin:

git commit --amend

Önceki, hatalı taahhüt yeni endeks durumunu yansıtacak şekilde düzenlenecektir - başka bir deyişle, en başta hiç hata yapmamışsınız gibi olacaktır.

Bunu yalnızca henüz itmediyseniz yapmanız gerektiğini unutmayın. Eğer ittiyseniz, normal olarak bir düzeltme yapmanız gerekir.


2
Bilginize: Bu tüm dosyalarımı siler ve değişiklikleri kaybettim.
egorlitvinenko

UPD: Ancak, reflog kullanarak geri yükledim. Ancak makbuz ilk taahhüt için işe yaramadı.
egorlitvinenko

1
Kullanım git rm --cacheddosya sisteminde dosyaları tutmak ve sadece git dizinden silmek için!
xuiqzy

1015
git rm yourfiles/*.class
git commit -a -m "deleted all class files in folder 'yourfiles'"

veya

git reset --hard HEAD~1

Uyarı: Yukarıdaki komut, yürütmek istediğiniz .javadosyalarda (ve diğer dosyalarda) yapılan değişiklikleri kalıcı olarak kaldıracaktır .

hard resetİçin HEAD-1senin yanlış gerçekleştirmeden önce taahhüt durumuna sizin çalışma kopyasını ayarlayacaktır.


19
git commit -a -m ""veya git commit -am ""doğal olarak! :]
trejder

Stash'ın başka bir 'kısayol' kullanımı; herşeyi bozmak istiyorsanız (git add geri al), sadece git stash, o zamangit stash pop
seanriordan08

778

Son taahhüdü değiştirmek için

Dizindeki dosyaları değiştirin:

git rm --cached *.class
git add *.java

Ardından, özel bir şubeyse , taahhüdü değiştirin :

git commit --amend

Veya paylaşılan bir şube ise yeni bir taahhütte bulunun:

git commit -m 'Replace .class files with .java files'


( Önceki bir taahhüdü değiştirmek için harika etkileşimli rebase'i kullanın .)


ProTip ™: Bunun tekrar olmasını durdurmak *.classiçin bir gidignore ekleyin .


Bir taahhüdü geri almak için

Bir taahhüdü değiştirmek, son taahhüdü değiştirmeniz gerekirse ideal çözümdür, ancak daha genel bir çözüm reset .

Git'i aşağıdakilerle herhangi bir işleme sıfırlayabilirsiniz:

git reset @~N

Nerede Nkaydedilmesini sayısı öncedir HEADve @~öncekine sıfırlar işlemek.

Yani, taahhüdü değiştirmek yerine şunları kullanabilirsiniz:

git reset @~
git add *.java
git commit -m "Add .java files"

Check out git help resetüzerine, özellikle bölümler --soft --mixedve --hardbu ne daha iyi anlamak için,.

Reflog

Dağılmışsanız, bırakılan taahhütleri bulmak için her zaman reflog'u kullanabilirsiniz:

$ git reset @~
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~
2c52489 HEAD@{1}: commit: added some .class files
$ git reset 2c52489
... and you're back where you started



2
İleride okuyanlar için - lütfen git revertbunun ayrı bir komut olduğunu unutmayın - temel olarak tek bir öğeyi 'sıfırlar'.
BKSpurgeon

681

Kullanın git revert <commit-id>.

Kimliğini taahhüt almak için, sadece kullanmak git log.


15
Bu ne anlama geliyor, kiraz taahhüdü seçiyor? Benim durumumda, bir dosyayı düzenlediğimde yanlış şubedeydim. Daha sonra yanlış şubede olduğumu fark ettim. "Git reset --soft HEAD ~ 1" komutunu kullandığımda işlemden hemen önce geri döndüm, ancak şimdi doğru şubeyi teslim alırsam, dosyadaki değişiklikleri yanlış dalda nasıl geri alabilirim, ancak onları (aynı adlı dosyası) doğru dalda?
astronomerdave

Ben sadece git revert commit-idbir cazibe gibi çalıştı kullanılır . Tabii ki değişikliklerinizi zorlamanız gerekecek.
Casey Robinson

8
Bunun git cherry-pick <<erroneous-commit-sha>>@astronomerdave olacağına inanıyorum . Bay Neredeyse-2 Yıl-Partiye Geç.
Tom Howard

@Kris: Kiraz toplama yerine rebase kullanın. Gelişmiş kiraz toplama olduğu için
Eugen Konkov

Geri almayı yalnızca taahhüdümü zaten itmiş olsaydım kullanırdım. Aksi takdirde, sıfırlama daha iyi bir seçenektir. Geri dönmenin yeni bir taahhüt yarattığını unutmayın ve genellikle bu amaç değildir.
Hola Soy Edu Feliz Navidad

532

Yerel bir taahhüdü tamamen geri almayı planlıyorsanız, değiştirdiğiniz her şeyi taahhütte yaptınız ve bununla ilgili herhangi bir endişe duymuyorsanız, aşağıdaki komutu uygulayın.

git reset --hard HEAD^1

(Bu komut tüm taahhüdünüzü yok sayar ve değişiklikleriniz yerel çalışma ağacınızdan tamamen kaybolur). Taahhütünüzü geri almak istiyorsanız, ancak hazırlama alanındaki değişikliklerinizi (tıpkı sonradan olduğu gibi tamamlamadan önce git add) istiyorsanız, aşağıdaki komutu yapın.

git reset --soft HEAD^1

Artık taahhütlü dosyalarınız hazırlama alanına giriyor. Diyelim ki dosyaları tersine çevirmek istiyorsanız, bazı yanlış içerikleri düzenlemeniz gerekiyor, ardından aşağıdaki komutu yapın

git reset HEAD

Şimdi aşamalı alandan düzensiz alana gelmesi için dosyalar taahhüt edildi. Artık dosyalar düzenlemeye hazır, bu nedenle ne değiştirirseniz düzenleyin ve ekleyin ve yeni / yeni bir taahhütte bulunun.

Daha


13
@SMR, Örneğinizde, hepsi yalnızca mevcut HEAD'ı gösteriyor. KAFA ^ = KAFA ^ 1. Ayrıca HEAD ^ 1 = HEAD ~ 1. HEAD ~ 2 kullandığınızda, ~ ve ^ sembolleri arasında bir fark vardır. ~ 2 kullanırsanız, “ilk ebeveynin ilk ebeveyni” veya “büyükbaba veya büyükanne veya büyükbaba” anlamına gelir.
Madhan Ayyasamy

501

Eğer varsa Git Ekstralar yüklü, Çalıştırabileceğiniz git undoson işlemeye geri almak. git undo 3son üç taahhüdü geri alacaktır.


470

Paylaşılan depomuzdaki son beş taahhüdü geri almak istedim. Geri almak istediğim düzeltme kimliğine baktım. Sonra aşağıdakileri yazdım.

prompt> git reset --hard 5a7404742c85
HEAD is now at 5a74047 Added one more page to catalogue
prompt> git push origin master --force
Total 0 (delta 0), reused 0 (delta 0)
remote: bb/acl: neoneye is allowed. accepted payload.
To git@bitbucket.org:thecompany/prometheus.git
 + 09a6480...5a74047 master -> master (forced update)
prompt>

25
Paylaşılan bir depoda geçmişi yeniden yazmak genellikle çok kötü bir fikirdir. Ne yaptığını bildiğini varsayıyorum, umarım gelecekteki okuyucular da yapar.
Brad Koch

Evet geri alma tehlikelidir. İçe basmadan önce çalışan kopyanızın istediğiniz durumda olduğundan emin olun. İtme sırasında istenmeyen taahhütler kalıcı olarak silinir.
neoneye

6
"Tıpkı gerçek dünyada olduğu gibi, tarihi yeniden yazmak istiyorsanız, bir komploya ihtiyacınız vardır: herkes komploda 'en azından' olmalıdır (en azından tarihi bilen herkes, yani şubeden çeken herkes) ." Kaynak: stackoverflow.com/a/2046748/334451
Mikko Rantalainen

440

git rebase -iBu iş için kullanmayı tercih ederim , çünkü kurtulmak için taahhütleri seçebileceğim güzel bir liste açılır. Buradaki diğer cevaplar kadar doğrudan olmayabilir, ama doğru hissettiriyor .

Kaç tane taahhütte bulunmak istediğinizi seçin, ardından şu şekilde çağırın (son üçünü kaydetmek için)

git rebase -i HEAD~3

Örnek liste

pick aa28ba7 Sanity check for RtmpSrv port
pick c26c541 RtmpSrv version option
pick 58d6909 Better URL decoding support

Ardından Git, kaldırdığınız tüm satırların taahhütlerini kaldıracaktır.


422

Önceki yerel taahhüt nasıl düzeltilir?

Gitmek için git-gui (veya benzeri) kullanın. git commit --amend . GUI'den tekli dosyaları tek tek ekleyebilir veya kaldırabilirsiniz. Teslim mesajını da değiştirebilirsiniz.

Önceki yerel taahhüt nasıl geri alınır

Şubenizi önceki konuma sıfırlamanız yeterlidir (örneğin, gitkveya kullanarak git rebase). Ardından, kaydedilmiş bir kopyadaki değişikliklerinizi yeniden uygulayın. Yerel deponuzda çöp toplandıktan sonra, istenmeyen taahhüt hiç gerçekleşmemiş gibi olacaktır. Tüm bunları tek bir komutta yapmak için tuşunu kullanın git reset HEAD~1.

Uyarı kelimesi : Dikkatsiz kullanımı, git resetçalışma kopyanızı kafa karıştırıcı bir duruma sokmanın iyi bir yoludur. Git acemilerin eğer yapabilirlerse bundan kaçınmasını tavsiye ederim.

Bir kamu taahhüdü nasıl geri alınır

Değişiklikleri geri almak için ters kiraz toplama ( git-revert ) yapın.

Şubenize henüz başka değişiklik yapmadıysanız, şunları yapabilirsiniz ...

git revert --no-edit HEAD

Ardından güncellenmiş dalınızı paylaşılan depoya aktarın.

Taahhüt tarihi her iki taahhüdü ayrı ayrı gösterir .


Gelişmiş: Kamu deposunda özel şubenin düzeltilmesi

Bu tehlikeli olabilir - tekrar şubenin yerel bir kopyasına sahip olduğunuzdan emin olun.

Ayrıca not: Şube üzerinde başka biri çalışıyorsa bunu yapmak istemezsiniz.

git push --delete (branch_name) ## remove public version of branch

Şubenizi yerel olarak temizleyin, sonra tekrar ...

git push origin (branch_name)

Normal durumda, muhtemelen özel şube taahhüt geçmişinizin bozulmamış olması konusunda endişelenmenize gerek yoktur. Sadece bir takip taahhüdünü itin (yukarıdaki 'Bir kamu taahhüdü nasıl geri alınır' bölümüne bakın) ve daha sonra geçmişi gizlemek için bir squash-merge yapın.


8
gitk --all $(git reflog | cut -c1-7)&"- değişiklik" taahhüdünü geri almak istiyorsanız önceki düzeltmeyi bulmak için yararlı olabilir.
nobar

4
Paylaşılan bir havuza gitmeden önce gizli bilgileri kaldırmaya çalışıyorsanız, bir geri döndürmenin size yardımcı olmayacağı unutulmamalıdır, çünkü bilgiler önceki işlemde hala tarihte olacaktır. Değişikliğin asla başkaları tarafından görülemediğinden emin olmak istiyorsanız kullanmanız gerekirgit reset
Jherico

Bence 'özel' / 'genel' daha doğru bir şekilde 'yerel' / 'uzak' olur.
nobar

Uzak depodaki özel bir dalı düzeltmek de basit bir şekilde yapılabilirgit push origin (branch_name) --force
nobar

335

Kalıcı olarak geri almak istiyorsanız ve bazı depoları klonladıysanız

Taahhüt kimliği şu şekilde görülebilir:

git log 

Sonra yapabilirsin -

git reset --hard <commit_id>

git push origin <branch_name> -f

"<commit_id>" komutunu kullanmaz ve "git reset --hard" komutunu kullanırsanız ne olur? Genellikle henüz işlemediğim en son güncellemelerimden kurtulmak ve yaptığım son işleme geri dönmek istiyorum ve her zaman "git reset --hard" kullanıyorum.
Jaime Montoya

3
@JaimeMontoya Son değişiklikleri geri almak için kullanabilirsiniz git reset --hard, ancak son "n" taahhütlerini
zorlamak zorunda kalırsanız

334

Önemsiz olduysanız ama itmediyseniz,

git reset --soft HEAD~1

HEAD ~ 1 , kafa önündeki taahhüt için bir kısayoldur. Alternatif olarak, eğer sıfırlamak isterseniz, karma değerinin SHA-1'ine başvurabilirsiniz . --soft seçeneği, taahhüdü siler ancak git durumunun koyacağı gibi, değiştirilen tüm dosyalarınızı "Yapılacak değişiklikler" olarak bırakacaktır.

Eğer baş önce taahhüt yerine çalışma ağacında izlenen dosyalarda herhangi bir değişiklik kurtulmak istiyorsanız yerine " --hard " kullanın.

VEYA

Zaten ittiyseniz ve genellikle benim durumum olan biri çektiyseniz git reset kullanamazsınız . Ancak bir git geri dönüşü yapabilirsiniz ,

git revert HEAD

Bu, kazara verilen taahhüt tarafından getirilen her şeyi tersine çeviren yeni bir taahhüt oluşturacaktır.


Ben ikinci durumda, ama "git HEAD geri döndürmek" yaptığımda "hata:" [ID] birleştirme olduğunu ancak hiçbir -m seçeneği verildi. Fatal: revert başarısız "diyor. Herhangi bir öneri?
metaforge

2
Muhtemelen HEAD~1sizin yerine gerçek hash'ı git log --statveya tarafından gösterilen şekilde kullanabileceğinizi belirtmek gerekir .git reflog değerini, birden fazla taahhüdü 'geri almanız' gerektiğinde faydalı olarak kullanabilirsiniz.
ccpizza

284

On SourceTree (GitHub'dan için GUI) kullanarak, taahhüt ve 'Ters Teslim' do sağ tıklayabilir. Bu, değişikliklerinizi geri almalıdır.

Terminalde:

Alternatif olarak şunları kullanabilirsiniz:

git revert

Veya:

git reset --soft HEAD^ # Use --soft if you want to keep your changes.
git reset --hard HEAD^ # Use --hard if you don't care about keeping your changes.

263

Tek bir komut:

git reset --soft 'HEAD^' 

Son yerel taahhüdü geri almak harika çalışıyor!


11
Git reset --soft "HEAD ^" yazmam gerekiyordu, çünkü Windows komut isteminden yazıyorum.
Ena

253

Sadece aşağıdaki komutu kullanarak sıfırlayın git:

git reset --soft HEAD~1

Açıklayın: ne git resetyapar, temelde resetgeri dönmek istediğiniz herhangi bir taahhüt için, o zaman --softanahtarla birleştirirseniz geri döner, ancak dosyalarınızdaki değişiklikleri koruyun, böylece sahneye geri dönersiniz dosyanın yeni eklendiği, HEADşubenin başıdır ve ~1(bu durumda da kullanırsanız HEAD^) ile birleştirirseniz, istediğiniz tek bir taahhüt geri döner ...

Gerçek görüntüde meydana gelebilecek ve kodun yerine getirilmesi ile ilgili tüm adımlar da dahil olmak üzere aşağıdaki görüntüdeki adımları sizin için daha ayrıntılı olarak oluşturuyorum:

Git'teki son işlemleri nasıl geri alabilirim?


239

Son Git taahhüdü nasıl geri alınır?

Her şeyi son işlemden önceki haline geri döndürmek için, HEAD'den önceki işleme sıfırlamamız gerekir.

  1. Yaptığınız değişikliklerinizi saklamak istemiyorsanız:

    git reset --hard HEAD^
    
  2. Değişikliklerinizi korumak istiyorsanız:

    git reset --soft HEAD^
    

Şimdi git günlüğünüzü kontrol edin. Son taahhüdümüzün kaldırıldığını gösterecek.


193

"Çalışma ağacını son işleme sıfırla"

git reset --hard HEAD^ 

"Çalışma ağacındaki bilinmeyen dosyaları temizle"

git clean    

bkz. - Git Hızlı Başvuru

NOT: Bu komut önceki işleminizi siler, bu yüzden dikkatli kullanın! git reset --harddaha güvenli.


190

Doğru bir durum bulmak için reflog'u kullanın

git reflog

daha önce yeniden yerleştir SIFIRLAMADAN ÖNCE REFLOG

Doğru reflog'u (benim durumumda f3cb6e2) seçin ve yazın

git reset --hard f3cb6e2

Bundan sonra, repo HEAD, RESET SONRASI SONRA o HEADid LOG'una sıfırlanacaktır efekti sıfırla

Sonunda reflog aşağıdaki resme benziyor

sonra yeniden REFLOG NİHAİ


164

İlk çalıştırma:

git reflog

Deponuzda gerçekleştirdiğiniz tüm olası işlemleri gösterir; örneğin, taahhüt, birleştirme, çekme vb.

Sonra şunları yapın:

git reset --hard ActionIdFromRefLog

155

Son taahhüdü geri al:

git reset --soft HEAD^ veya git reset --soft HEAD~

Bu son taahhüdü geri alacaktır.

Burada --softevrelemeye sıfırlama anlamına gelir.

HEAD~veya HEAD^HEAD öncesinde taahhütte bulunmak için harekete geçmek anlamına gelir.


Son taahhüdü yeni taahhüt yerine değiştir:

git commit --amend -m "message"

Son taahhüdü yeni taahhütle değiştirecektir.


153

Diğer yol:

Geri döndürmek istediğiniz dalı kontrol edin, ardından yerel çalışma kopyanızı uzak sunucuda en son olmasını istediğiniz taahhüde sıfırlayın (her şey güle güle gidecektir). Bunu yapmak için, SourceTree'de sağ tıkladım ve "BRANCHNAME'i bu işleme sıfırla" yı seçtim.

Ardından deponuzun yerel dizinine gidin ve şu komutu çalıştırın:

git -c diff.mnemonicprefix=false -c core.quotepath=false push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

Bu işlem, yerel deponuzdaki geçerli olandan sonraki tüm taahhütleri silecektir, ancak yalnızca bu dal için.


144

Yazın git logve son tamamlama karma kodunu bulmak ve enter:

git reset <the previous co>

139

Benim durumumda istemediğim bazı dosyaları yanlışlıkla işledim. Bu yüzden aşağıdakileri yaptım ve işe yaradı:

git reset --soft HEAD^
git rm --cached [files you do not need]
git add [files you need]
git commit -c ORIG_HEAD

Sonuçları gitk veya git log --stat ile doğrulayın


133

Basit, bunu komut satırınızda çalıştırın:

git reset --soft HEAD~ 

126

Bunu yapmanın birçok yolu vardır:

Son komutu / önceki taahhütleri geri almak için Git komutu:

Uyarı: Ne yaptığınızı bilmiyorsanız --hard kullanmayın. --hard çok tehlikelidir ve dosyalarınızı silebilir.

Git'teki taahhüdü geri almak için temel komut:

$ git reset --hard <COMMIT -ID>

veya

$ git reset --hard HEAD~<n>

COMMIT-ID : Taahhüt için kimlik

n: geri almak istediğiniz son taahhütlerin sayısıdır

Taahhüt kimliğini aşağıda gösterildiği gibi alabilirsiniz:

$ **git log --oneline**

d81d3f1 function to subtract two numbers

be20eb8 function to add two numbers

bedgfgg function to mulitply two numbers

burada d81d3f1 ve be20eb8 kaydedilmiş kimliklerdir.

Şimdi bazı vakalara bakalım:

Son işlem olan 'd81d3f1' i geri almak istediğinizi varsayalım. İşte iki seçenek:

$ git reset --hard d81d3f1

veya

$ git reset --hard HEAD~1

'Be20eb8' taahhüdünü geri almak istediğinizi varsayalım:

$ git reset --hard be20eb8

Daha ayrıntılı bilgi için, başlığı belirtilen bir duruma sıfırlamak için başka komutlara da başvurabilir ve deneyebilirsiniz:

$ git reset --help

5
git reset --hard HEAD~1olduğunu çok tehlikeli ! Bu sadece 'son taahhüdü iptal etmekle kalmayacak, aynı zamanda repoyu bir önceki taahhüdüne geri döndürecektir. Böylece son taahhütte yapılan tüm değişiklikleri KAYBEDECEKSİNİZ!
Arnis Juraga

Doğru, bunu geri almak için kullanabilirsinizgit push -f <remote> HEAD@{1}:<branch>
Benny

Ne yazık ki, --hard kullanıyorum ve dosyalarım silindi! İlk önce yorumu kontrol etmedim çünkü çöktü. Ne yaptığınızı bilmiyorsanız --hard kullanmayın!
anonim

125

Yerel bir taahhüt için

git reset --soft HEAD~1

veya tam olarak hangi taahhütte olduğunu hatırlamıyorsanız,

git rm --cached <file>

İtilmiş bir taahhüt için

Depo geçmişinden dosyaları kaldırmanın doğru yolu kullanıyor git filter-branch. Yani,

git filter-branch --index-filter 'git rm --cached <file>' HEAD

Ama bu komutu dikkatli bir şekilde kullanmanızı tavsiye ederim. Git-filter-branch (1) Kılavuz Sayfasında daha fazlasını okuyabilirsiniz .


125

İki ana senaryo var

Henüz taahhütte bulunmadınız

Sorun, taahhüt ettiğiniz fazladan dosyadaysa (ve depodaki dosyaları istemiyorsanız), bunları kullanarak git rmve ardından--amend

git rm <pathToFile>

Ayrıca tüm dizinleri kaldırabilir -rve hatta diğer Bash komutlarıyla birleştirebilirsiniz

git rm -r <pathToDirectory>
git rm $(find -name '*.class')

Dosyaları kaldırdıktan sonra --amend seçeneğiyle işlem yapabilirsiniz.

git commit --amend -C HEAD # the -C option is to use the same commit message

Bu, ekstra dosyaları kaldırarak son yerel taahhüdünüzü yeniden yazacaktır, bu nedenle bu dosyalar asla push'a gönderilmez ve GC tarafından yerel .git deponuzdan kaldırılır.

Taahhüdünü zaten ittin

Sen yaparak daha sonra aynı diğer senaryonun çözümü ve uygulayabilirsiniz git pushile -fseçeneği, ancak edilir önerilmez bir ıraksak değişikliği ile uzaktan tarihini yazar beri (o karışıklık senin depo can).

Bunun yerine, taahhüdü olmadan yapmak zorundasınız --amend(-amend`i hatırlayın: Bu seçenek, tarihi son taahhütte yeniden yazar).


125

Bir önceki düzeltmeye sıfırlamak için, taahhüt edilmeyen tüm değişiklikleri kalıcı olarak silmek:

git reset --hard HEAD~1

23
Belki de emrinde, komutunun iş dizinindeki değişiklikleri ve değişiklikleri daha fazla sormadan atacağına dair bir not / uyarı verebilirsiniz .
cr7pt0gr4ph7


13
Kullanım --softolarak değişiklikleri tutmak için uncommitted changes, --hardtamamen ve tek Geri döndürme geri işlemek uçurmadın. Bu tür işlemleri sadece henüz itilmemiş değişikliklerde yapmayı unutmayın.
Yunus Nedim Mehel

@Zaz: Haklısın; belki bunu açıklığa kavuşturmalıydım. Yalnızca dizine eklenen (/ aşamalı) veya kaydedilmiş olan dosyalar / değişiklikler kurtarılabilir. İhtiyat, unstaged değişiklikler vardır dediğin gibi, tamamen tarafından atılır git reset --hard.
cr7pt0gr4ph7

1
Sidenote olarak: Her dosya hazırlandığında gitiçeriğini nesne veritabanında saklar. Depolanan içerik yalnızca çöp toplama işlemi yürütüldüğünde kaldırılır. Bu nedenle git reset --hard, yürütülmekte olan sırada hazırlanmamış olan bir dosyanın son aşamalı sürümünü kurtarmak mümkündür (daha fazla bilgi için yukarıdaki bağlantılara bakın).
cr7pt0gr4ph7
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.