Soru Git'deki en son işlemleri nasıl geri alabilirsiniz?


Yanlışlıkla yanlış dosyalar yaptım Gitama henüz bu işlemi sunucuya itmedim.

Bu depoları yerel depodan nasıl geri alabilirim?


17823
2017-07-28 22:22


Menşei


Uyarı: Sadece bunu bir uzaktan kumandaya henüz ittiyseniz yapmalısınız, aksi takdirde uzaktan kumandadan gelen diğer kişilerin geçmişini bozacaksınız! - thSoft
İşte çok net ve kapsamlı bir yazı Github dan git, git şeyleri geri alma hakkında. - Nobita
Yerel, Public ve Git Şubelerinde Git işlemlerini geri almak için bu kılavuza bakın Git gibi Git Komitleri nasıl geri alınır - Luzan Baral
Yeni bir cevap göndermeden önce, bu soru için şimdiden 65'den fazla yanıt olduğunu düşünün. Cevabınızın, mevcut cevaplar arasında olmayanlara katkıda bulunduğundan emin olun. - Sazzad Hissain Khan
Git'in neye ihtiyacı olduğunu biliyor musun? git undo, bu kadar. Daha sonra git itibarı, bizim tarafımızdan yapılan hataların üstesinden gelmek için sadece ölümlüler ortadan kalkar. Herhangi bir işlemi gerçekleştirmeden önce mevcut durumu bir git yığınının üzerine iterek uygulayın. gitKomut. Performansı etkiler, bu yüzden etkinleştirilip etkinleştirilmeyeceğine bir yapılandırma bayrağı eklemek en iyisidir. - Yimin Rong


Cevaplar:


Bir işlemi geri al ve tekrar yap

$ 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. Bunu geri almak istediğiniz şey budur
  2. Bu, çalışma ağacınızı (diskinizdeki dosyaların durumu) değişmeden bırakır, ancak taahhütleri kaldırır ve tahakkuk etmiş olduğunuz değişiklikleri bırakır (böylece "İşlem için hazırlanmayan değişiklikler" olarak görünürler) git statusve işlem yapmadan önce onları tekrar eklemeniz gerekir). Eğer sen bir tek istemek eklemek Bir önceki işleme daha fazla değişiklik veya taahhüt mesajını değiştirme1, kullanabilirsin git reset --soft HEAD~ bunun yerine, hangisi git reset HEAD~ (nerede HEAD~ aynıdır HEAD~1) ancak mevcut değişikliklerinizi aşamalı olarak bırakır.
  3. Çalışan ağaç dosyalarında düzeltmeler yapın.
  4. git add Yeni işleminize dahil etmek istediğiniz her şey.
  5. Eski taahhüt mesajını yeniden kullanarak değişiklikleri tamamlayın. reset eski kafayı kopyaladı .git/ORIG_HEAD; commit ile -c ORIG_HEAD başlangıçta eski taahhütten günlük mesajını içeren ve düzenlemenize izin veren bir editör açacaktır. Mesajı düzenlemeniz gerekmiyorsa, -C seçeneği.

Ancak, dizine yeni değişiklikler eklediyseniz, şunu kullanın: commit --amend onları önceki işleminize ekleyecektir.

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

git push origin master --force

Ayrıca bu cevaba da bakabilirsiniz:

HEAD, önceki bir konuma nasıl geri alınır? (Müstakil kafa)

Yukarıdaki cevap size gösterecek git reflog Hangi geri dönmek istediğiniz SHA-1 olduğunu öğrenmek için kullanılır. Yukarıda açıklandığı gibi komut dizisini kullanmak için geri almak istediğiniz noktayı bulduktan sonra.


1 Bununla birlikte, daha önce yaptığınız bir hatayı düzeltmek zorunda kalmazsanız, daha önceki bir işleme sıfırlamanıza gerek olmadığını unutmayın. taahhüt mesajı. Daha kolay seçenek git reset (o zamandan beri yaptığınız değişikliklerin üstesinden gelmek için) ve sonra git commit --amendSon taahhüt mesajıyla önceden doldurulmuş varsayılan taahhüt mesaj düzenleyicinizi açar.


19285
2018-06-16 17:27



Ve eğer taahhüt yanlış şubeye gitmiş olsaydı, belki git checkout theRightBranch tüm değişiklik aşamaları ile. Yapmam gereken gibi. - Frank Shearar
DOS'ta çalışıyorsanız, yerine git reset --soft HEAD^ kullanman gerekecek git reset --soft HEAD~1. ^, DOS'ta devam eden bir karakter olduğundan düzgün çalışmaz. Ayrıca, --soft varsayılan, bu yüzden isterseniz ve sadece söyle eğer ihmal edebilirsiniz git reset HEAD~1. - Ryan Lundy
Ayrıca, zsh'de ^ yazmanız gerekir. git reset --soft 'HEAD^'... en azından ben yaptım - jberryman
(Yukarıda yazdıklarımın düzeltilmesi; --mixed varsayılan değerdir. --mixed değiştirilen dosyaları tutmak anlamına gelir, ancak bunları dizinde tutmaz. --soft değiştirilen dosyaları saklar ve değiştirilen işlemden hemen önce olduğu gibi dizinde saklar. Karışıklık için özür dilerim.) - Ryan Lundy
zsh kullanıcıları alabilir: zsh: no matches found: HEAD^ - kaçman gerek. git reset --soft HEAD\^ - tnajdek


Nasıl çalıştığını bilmiyorsanız, bir taahhüdün geri alınması biraz korkutucu. Ama eğer anlıyorsan, aslında inanılmaz derecede kolay.

Bunu aldığınızı söyleyin, C sizin HEAD'ınız ve (F) dosyalarınızın durumu.

   (F)
A-B-C
    ↑
  master

İstiyorsun Nuke C ve bir daha asla görmeyecek. Bunu yap:

git reset --hard HEAD~1

Sonuç:

 (F)
A-B
  ↑
master

Şimdi B, BAŞ. Çünkü kullandın --hard, dosyalarınız B işleminde durumlarına sıfırlanır.

Ah, ama sanırım C işlemesi bir felaket değildi, ama sadece biraz kapalı. İstiyorsun İşlemi geri al, ancak değişikliklerini sakla Daha iyi bir işlem yapmadan önce biraz düzenleme yapmak için. Buradan tekrar başlayarak, CÜ'nizle birlikte C:

   (F)
A-B-C
    ↑
  master

Bunu yapabilirsin, bırakarak --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. Ne zaman git reset HEAD~1Git'e, HEAD işaretçisini bir taahhütte geri götürmesini söylersin. Ama sen kullanmadıkça --hard) dosyalarınızı oldukları gibi bırakırsınız. Peki şimdi git status C'ye kontrol ettiğiniz değişiklikleri gösterir. Bir şeyi kaybetmediniz!

En hafif dokunuş için bile taahhüdünü geri al, ancak dosyalarınızı ve indeks:

git reset --soft HEAD~1

Bu sadece dosyalarınızı tek başına bırakmaz; indeks yalnız. Ne zaman yaparsın git statusAynı dosyaların daha önce olduğu gibi dizin içinde olduğunu göreceksiniz. Aslında, bu komutadan sonra yapabilirsin git commit ve sahip olduğunuzın aynısını tekrarlarsın.

Bir şey daha: Bir işlemi yok ettiğinizi varsayalım ilk örnekte olduğu gibi ama sonra ihtiyacın olduğunu keşfettim? Zor şans, değil mi?

Hayır, orada yine Onu geri almak için bir yol. tip git reflog ve etrafta dolaştığınız (kısmi) işleyen şakaların bir listesini göreceksiniz. İmha ettiğiniz işlemi bulun ve şunu yapın:

git checkout -b someNewBranchName shaYouDestroyed

Şimdi bu işi tekrar yaptın. Komutalar, Git'de 90 gün boyunca yok edilmezler, bu yüzden kurtulmak istemediğiniz birisini geri dönüp kurtarmaya devam edebilirsiniz.


9734
2018-05-29 18:16



@dma_k, evet. Ya da yapabilirsin git reset --hard HEAD^^ bir Zamanlar. Tilde (~) gösterimini kullanıyorum çünkü karta (^) gösterimi DOS'ta çalışmıyor. - Ryan Lundy
Başka bir güzel ipucu: Şubeyi, kaldırdığınız taahhütle yeniden ekleyebilirsiniz. git branch -f <branch> <commit-id>. İşlemleri yeniden oluşturmaya gerek kalmadan kaydeder! - naught101
Git yeni başlayan biri için, son iki seçenek arasındaki farkın ne olduğu belli değil (--soft ve üstündeki). Endekse değinmek yardımcı olmuyor, bunun ne anlama geldiğini gerçekten bilmiyoruz. @ nessur'un yumuşak ve Ctrl-Z arasındaki bağlantı gerçekten yardımcı oldu! Ama hala iki seçenek arasındaki farkı anlamıyorum. - Stomp
'Neden' bir şeyin işe yarayacağını söylemek, cevabın sadece söylenmesinden daha iyidir. Bu açıklamaya Kudos - bu 'get' git yardımcı oldu. - Chris Nash
Önemli bir noktayı atlamak: Eğer söz konusu taahhüt daha önce uzaktan kumandaya “itilmişse”, herhangi bir 'geri al' işlemi, ne kadar basit olursa olsun, yerel kopyasında bu işi yapan kullanıcıların geri kalanına muazzam bir acı ve ıstıraba neden olacaktır. Gelecekte bir 'git çekme' yaptıklarında. Bu yüzden, eğer bu işlem zaten 'itilmiş' ise, bunun yerine şunu yapın: git <bad-commit-sha1-id> git push origin: - FractalSpace


Bu anlamaya biraz zamanımı aldı, belki bu birilerine yardım eder ...

Son taahhüdünüzü "geri almayı", bağlılığınızı zaten kamuya açık hale getirip getirmediğinize (uzak deponuza ittiniz) bağlı olarak iki yol vardır:

Yerel bir işlem nasıl geri alınır?

Yerel olarak işlediğimi varsayalım, ancak şimdi bu işlemi kaldırmak istiyoruz.

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

Her şeyi en son işlemden önceki yola geri döndürmek için reset daha önce taahhüt 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 log Son taahhüdümüzün kaldırıldığını gösterecek.

Bir kamu taahhüdünün nasıl geri alınacağı

İşlemlerinizi herkese açık hale getirdiyseniz, önceki işleminizde (mevcut HEAD) yaptığınız değişiklikleri "geri döndürecek" yeni bir taahhüt oluşturmak istersiniz.

git revert HEAD

Değişiklikleriniz şimdi 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, göz atın Git Temelleri - Şeyler Geri Alma


1751
2018-05-29 18:13



Bu cevabı en net buldum. git revert HEAD^ önceki değil, önceki önceki. Yaptım : git revert HEAD ve sonra tekrar bas ve işe yaradı :) - nacho4d
@riezebosch: uyarınız yanlış yerde. BU cevap bir şeyleri kirletmez, doğru bir şekilde yeni bir taahhüt yaratır. 102: "kazada kaldırdığım dosyayı geri yükleme" - rubo77
Bu en iyi cevabı çünkü git geçmişini karıştırmıyor - Lukas


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

git rm classdir
git add sourcedir

Daha sonra bu taahhüdü değiştir:

git commit --amend

Önceki, hatalı işlem, yeni dizin durumunu yansıtacak şekilde düzenlenecektir - başka bir deyişle, hiç hata yapmadığınız gibi olacak.

Henüz itmediyseniz bunu yapmalısınız. Eğer ittiyseniz, o zaman normal olarak bir düzeltme yapmak zorunda kalacaksınız.


1625
2017-07-31 09:39



Yaptığımda bu işe yarar mı git commit --amend ve gerçekten yapmak istediğim şey bir git commit? - dbm
@dbm, yanlışlıkla değiştirildiyseniz, kullanın git reset --soft <oldref>, değişiklikten önceki taahhütname eskidir. Kullanabilirsiniz git reflog eski taahhüt kimliğini tanımlamak için. Bu, değişikliğin etkilerini ortadan kaldıracak, ancak değişikliklerin aşamalı olarak gerçekleşmesini sağlayacaktır. O zaman sadece yap git commit düzenli bir taahhütte bulunmak. - bdonlan
@Dennis, git commit --amend geçerli ağacı (yani, aşamalı değişiklikler) bir taahhüt, üzerine yazılan geçerli KAFA'ya dönüştürür. Bu noktadan sonra, artık sahnelenmemiş sayılırlar çünkü onlar, söz konusu işlemin bir parçası (yani, git diff --cached boştur), ancak "kaldırılmış" veya "kayıp" değiller. - bdonlan


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, değişikliklerin kalıcı olarak kaldırılmasını sağlar. .java işlemek istediğiniz dosyaları (ve diğer dosyaları).

hard reset için HEAD-1 Çalışan kopyanızı, yanlış taahhütünüzden önce taahhüdün durumuna getirecektir.


878
2018-05-25 16:04



"--hard", işlemek istediği çalışma dizinindeki değiştirilmiş .java dosyalarından kurtulacaktır. - Esko Luontola
Yumuşak sıfırlama daha basit olurdu, ancak çalışma kopya değişiklikleri "git saklamak", bir sabit sıfırlama ve daha sonra onları geri almak için "git stash pop" yapabilirsiniz. - Asad R.
git commit -a -m "" veya git commit -am "" doğal olarak! :] - trejder
Başka bir 'kısayol' stash kullanımı; herşeyi kaldırmak isterseniz (geri al) git, sadece git stash, sonra git stash pop - seanriordan08


Son işlemi değiştirmek için

Dizindeki dosyaları değiştirin:

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

Sonra, eğer özel bir dalsa, değiştirmek taahhüt:

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 işlemi değiştirmek için, harikaları kullan etkileşimli rebase)


ProTip: Ekle *.class bir gitignore Bunu tekrar durdurmak için.


Bir işlemi geri almak için

Bir taahhütte değişiklik yapmak, son taahhüdünü değiştirmeniz gerektiğinde ideal çözümdür, ancak daha genel bir çözümdür. reset.

Git'i herhangi bir işleve sıfırlayabilirsiniz:

git reset @~N

Nerede N önceki işlem sayısıdır HEAD, ve @~ önceki taahhüte sıfırlanır.

Bu nedenle, işlemi değiştirmek yerine aşağıdakileri kullanabilirsiniz:

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

Çıkış yapmak git help resetözellikle bölümleri --soft  --mixed ve --hardBunun ne olduğunu daha iyi anlamak için.

Reflog

Dağınıklık yaparsanız, bırakılan taahhütleri bulmak için her zaman yeniden aramayı 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



679
2018-01-31 07:06



Gelecekte okuyanlar için lütfen unutmayın git revert ayrı bir komuttur - temel olarak 'tek bir commimt' sıfırlar. - BKSpurgeon


kullanım git revert commit-id

İşlem kimliğini almak için sadece kullan git log


549
2017-12-13 10:18



Yanlış şubeye karar verdiyseniz: bir kez geri döndüğünüzde, doğru şubeye geçin ve vekaleti seçin. - Kris
Bu ne demek oluyor, kiraz bu işi nasıl alacak? Benim durumumda, bir dosyayı düzenlediğimde yanlış daldaydım. Bunu yaptım sonra yanlış dalda olduğumu farkettim. "Git reset --soft HEAD ~ 1" komutunu kullanmadan hemen önce bana geri döndüm, ancak şimdi doğru şubeyi kontrol edersem, dosyadaki değişiklikleri yanlış dalda nasıl geri alabilirim ama (aynı isimle) dosya) doğru dalda mı? - astronomerdave
Az önce kullandım git revert commit-id cazibe gibi çalıştı. Tabii ki değişikliklerinizi zorlamanız gerekecek. - Casey Robinson
Bunun olduğuna inanıyorum git cherry-pick <<erroneous-commit-sha>> @astronomerdave. Bay, neredeyse 2-yıl-partiden partiye. - Tom Howard


Tamamen yerel bir işlemi iptal etmeyi planlıyorsanız, taahhütte ne yaptığınızı değiştirirseniz ve bununla ilgili hiçbir endişeniz yoksa, sadece aşağıdaki komutu yapın.

git reset --hard HEAD^1

(Bu komut tüm işleminizi görmezden gelecektir ve değişiklikleriniz tamamen yerel çalışan ağaçlarınızdan kaybolacaktır). Taahhüdünü geri almak istiyorsanız, ancak değişikliklerinizin hazırlama alanında olmasını istiyorsanız git add) Daha sonra aşağıdaki komutu yapın.

git reset --soft HEAD^1

Artık sizin taahhüt ettiğiniz dosyalar hazırlama alanına geliyor. Dosyaları kaldırmak istiyorsanız, yanlış bir düzenleme yapmanız gerekiyorsa, aşağıdaki komutu yapın.

git reset HEAD

Artık işlenen dosyalar sahnedeki alandan işaretsiz bölgeye geliyor. Artık dosyalar düzenlemeye hazır, bu yüzden ne yaparsanız yapın, düzenlemeye devam edin ve ekleyip yeni / yeni bir taahhütte bulunun.

Daha


441
2018-04-06 13:58



@SMR, Örneğinizde, hepsi sadece geçerli HEAD'a işaret ediyor. HEAD ^ = KAFA ^ 1. HEAD ^ 1 = HEAD ~ 1'in yanı sıra. HEAD ~ 2 kullandığınızda, ~ ve ^ sembolleri arasında bir fark vardır. Eğer ~ 2 kullanırsanız, “ilk ebeveyne ait ilk ebeveyn” veya “büyükbaba” anlamına gelir. - Madhan Ayyasamy
Açık ve anlaşılması kolay, gecemi kurtar! - Vladimir Ch
Görünüşe göre, kazara bu cevabı reddettim ve onu reddetmek için çok geç. Özür. - Matt


Eğer varsa Git Ekstraları yüklü, çalıştırabilirsiniz git undo son taahhüdü geri almak için. git undo 3 son 3 işi iptal edecek.


431
2017-10-25 03:41





Paylaştığımız havuzdaki en son 5 işi geri almak istedim. Geri dönmek istediğim revizyon kimliğine baktım. Sonra 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>

399



Paylaşılan bir depodaki geçmişin yeniden yazılması genellikle çok kötü bir fikirdir. Ne yaptığınızı bildiğini düşünüyorum, sadece gelecekteki okuyucuların da umarım. - Brad Koch
Evet geri alma tehlikelidir. Basmadan önce çalışma kopyanızın istediğiniz durumda olduğundan emin olun. İlerleyen zamanlar istenmeyen postalar kalıcı olarak silinir. - neoneye
"Tıpkı gerçek dünyada olduğu gibi, tarihi yeniden yazmak istiyorsanız, bir komploya ihtiyacınız var: Herkes komploda (en azından tarihini bilen herkes, yani daldan çektiği herkes)" içeride "olmak zorundadır. ." Kaynak: stackoverflow.com/a/2046748/334451 - Mikko Rantalainen
fantastik. Bu bir çekicilik gibi çalıştı. Bağımsız olarak çalışan geliştiriciler için bir git seçeneği olmalı - GitX'i veya bir işlemin yanındaki bir silme düğmesini ve bir onaylamayı kullanabilirsiniz - bu işlem bu kadar esrarengiz değildir :) - zero_cool


Kullanmayı tercih ederim git rebase -i Bu iş için, çünkü kurtulmak için taahhütleri seçebileceğim güzel bir liste açılır. Diğer bazı cevaplar kadar doğrudan olmayabilir, ama sadece doğru geliyor.

Kaç tane işlemek istediğinizi seçin, sonra bu şekilde çağırın (son üçü kaydetmek için)

git rebase -i HEAD~3

Örnek listesi

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

Daha sonra git, kaldırdığınız herhangi bir satır için işlemleri kaldıracaktır.


381