Geri döndürülmüş bir Git taahhüdünü nasıl "geri alırım"?


486

Kullanmayı taahhüt eden commitve sonra geri döndürülen bir değişiklik göz önüne alındığında , revertbu geri dönüşü geri almanın en iyi yolu nedir?

İdeal olarak, bu, tarihi yeniden yazmamak için yeni bir taahhütle yapılmalıdır.



@phuclv orada olası kopya için bir yorum, burada işaret ediyor. Biri orijinal, diğeri çift olarak işaretlenmelidir
John Demetriou

@JohnDemetriou daha iyi cevapları olan soru açık tutulmamalıdır. Zaman burada önemli değil Yinelenen sorular nasıl ele alınmalı?
phuclv

Zaman hakkında söylemedim. Konu hakkında iki kişiden birine yorum yaptım
John Demetriou

Yanıtlar:


385

Bu değişikliği henüz yapmadıysanız, git reset --hard HEAD^

Aksi takdirde, geri döndürmenin mükemmel bir şekilde yapılması iyi olur.

Başka bir yol git checkout HEAD^^ -- .ve sonra git add -A && git commit.


8
Orijinal değişiklikleri ana dalda hemen uygulamadan geri dönmek isterseniz, (1) silindiyse orijinal dalı geri yükleyebilir, (2) Adam tarafından not edildiği gibi geri döndürme dalında "geri dön" düğmesini tıklayabilirsiniz , ardından ( 3) sonuçta elde edilen PR başlığında "düzenle" yi tıklayın ve hedef dalı master yerine orijinal şubeye değiştirin. Artık orijinal dalınız daha önce geri döndürülen değişiklikleri etkilemek için yeniden birleştirilebilir.
pauljm

1
Lütfen bunun çalışma ağacı ve dizindeki tüm değişiklikleri kaldıracağını unutmayın. Kaybetmek istemediğiniz değişiklikleri kaydetmek için git stash kullanın.
zpon

3
Ödeme ve taahhüt yönteminin avantajı nedir? Genel durumda git cherry-pickya da alternatif git revertolarak bir geri dönüşü geri almanın en basit yolu olduğu görülmektedir.
Robert Jack

5
Nasıl yapılacağını göstermenin Otherwise, reverting the revert is perfectly fine.ve sonra ne git checkout HEAD^^ -- .yaptığını açıklamanın yararlı olacağını düşünüyorum .
Todd

3
Tanrım, kullanmayın git add -A... her dosyayı sürüm kontrolüne eklemek istemiyorsanız, büyük olasılıkla istediğiniz şey değildir.
Kaitain

474

git cherry-pick <original commit sha>
Esas taahhüdün bir kopyasını oluşturur, esasen taahhüdü yeniden uygular

Geri dönüşü geri almak aynı şeyi daha karışık bir mesajla yapar:
git revert <commit sha of the revert>

Bu yollardan her ikisi de git pushtarihin üzerine yazmadan size izin verecektir , çünkü geri döndükten sonra yeni bir taahhüt yaratır.
Taahhüt sha yazarken, genellikle yalnızca ilk 5 veya 6 karaktere ihtiyacınız vardır:
git cherry-pick 6bfabc


61
Bu, OP sorusu için kolayca en şık ve eksiksiz çözümdür. Taahhüt ağacının KAFASINDA olma yönündeki geri dönüş taahhüdü ile kabul edilen cevaptan çok daha iyi. Operatör ayrıca, geçmişi yeniden yazmayan bir çözüm de istedi, bu nedenle kabul edilen cevapta sunulan zor çözüm sadece yanlış.
Timo

6
@Timo Açıklığa kavuşturmak için, kabul edilen cevap kullandığım çözümü ("geri döndürme") içeriyor ve sorumdan birkaç saat sonra - bu yanıttan 3 yıl önce - açıklandı . Bu nedenle, onay işareti.
JimmidyJoo

6
@JimmidyJoo 3 yıl geç kaldığımı biliyorum, sadece bir google aramadan buraya gelen insanların daha iyi bir yanıt görmelerini istedim
Stephan

2
@Stephan Yep, ama yine, açıklığa kavuşturmak için - bu sadece sorunumu çözmek için kullandığım daha iyi bir cevap değil. Sadece onay işaretinin nerede olduğu hakkında yorum yapıyordum. Herkes için soru: SO konvansiyonu geçmiş sorularımı "sürdürmem" ve yeni cevaplar geldikçe onay işaretlerini yeniden atamamı gerektiriyor mu?
JimmidyJoo

3
@JimmidyJoo SO konvansiyonu hakkında hiçbir fikrim yok. Ancak bir google araştırmacısı olarak, daha iyi yanıtın kontrol edilmesini gerçekten tercih ederim. Ve kimsenin geçmişteki sorularını koruma çabalarını takdir eder.
Paiman Roointan

28

Bir geri dönüş taahhüdü git'deki diğer tüm taahhütler gibidir. Anlamı, şu şekilde geri alabilirsiniz:

git revert 648d7d808bc1bca6dbf72d93bf3da7c65a9bd746

Bu sadece değişiklikler itildikten sonra ve özellikle hedef şubeye zorlanamadığınızda mantıklıdır (bu, ana dalınız için iyi bir fikirdir ). Değişiklik aktarılmadıysa, sadece kiraz toplama yapın, geri alın veya diğer gönderilere göre geri alma taahhüdünü kaldırın.

Ekibimizde, esas olarak geçmişi temiz tutmak için ana dalda taahhüt edilen Revert taahhütlerine geri dönme kuralımız var , böylece hangi taahhüdün neyi geri döndürdüğünü görebilirsiniz:

      7963f4b2a9d   Revert "Revert "OD-9033 parallel reporting configuration"
      "This reverts commit a0e5e86d3b66cf206ae98a9c989f649eeba7965f.
                    ...
     a0e5e86d3b6    Revert "OD-9055 paralel reporting configuration"
     This reverts commit 648d7d808bc1bca6dbf72d93bf3da7c65a9bd746.
                ...
     Merge pull request parallel_reporting_dbs to master* commit 
    '648d7d808bc1bca6dbf72d93bf3da7c65a9bd746'

Bu şekilde, tarihi izleyebilir ve tüm hikayeyi anlayabilirsiniz ve miras bilgisi olmayanlar bile kendileri için çalışabilirler. Eğer varsa, Oysa kiraz almak veya Rebase şeyler, bu değerli bilgileri kaybolur (eğer yorumunda dahil sürece).

Açıkçası, bir taahhüt birden fazla kez geri döndürülür ve geri döndürülürse, bu oldukça dağınık hale gelir.


14

Geri döndürmek hile yapacak

Örneğin,

Eğer abcdefsenin işlemek ve ghijklsize kesinleştirme döndürüldü olduğunda aklınıza işlemek abcdef, sonra çalıştırın:

git revert ghijkl

Bu geri döner


4

Benim için aptalca görünüyor. Ama aynı durumdaydım ve geri çevrilmiş taahhütlere geri döndüm. Numara geri dönüşleri yaptım, bu yüzden her 'geri dönüş taahhüdü' için geri dönüş yapmak zorunda kaldım.

Şimdi benim tarihim biraz garip görünüyor.

garip tarih

Bir evcil hayvan projesi bu yüzden sorun yok. Ancak gerçek hayat projesi için, geri döndürülmeden önce geri alınan tüm kodları tek bir taahhütte ve daha makul bir yorumda geri yüklemeden önce son işleme gitmeyi tercih ederim.


4
Başka bir sorunuzun cevaplarıyla ilgilenebilirsiniz: stackoverflow.com/questions/10415565/…
JimmidyJoo

2
Otomatik taahhütten kaçınabilir ve geri dönerken --no-commit bayrağını kullanarak mesaj vermeyi ve ardından ilgili mesajı taahhüt etmeyi seçebilirsiniz
David Barda

Ayrıca git revert kullanırken birden fazla taahhüt kimliği belirtebilirsiniz (bence doğru sırada olmaları gerekir).
Aalex Gabi

Bunu github masaüstünden yapabilir miyim?
Guillaume F.

4

Şöyle yaptım:
Şube my_branchnamegeri döndürülen bir birleştirmeye dahil edildiyse . Ve geri dönmek istedim my_branchname:

Önce bir do git checkout -b my_new_branchnamedan my_branchname.
Sonra ilk taahhütten hemen önce taahhüdün taahhüt karmasını bir git reset --soft $COMMIT_HASHyer yapıyorum (bkz. ) Sonra yeni bir taahhütte bulunuyorum Sonra yeni şubeyi itiyorum Sonra yeni şube için bir talepte bulundum.$COMMIT_HASHmy_branchnamegit log
git commit -m "Add back reverted changes"
git push origin new_branchname


Yapmak için çok fazla "kiraz toplama" olduğunda gitmek için bir yol. Bu cevabın neden bu kadar az oyu olduğunu anlamıyorum
Fundhor

2

Veya yapabilirsin git checkout -b <new-branch>ve git cherry-pick <commit>önce ve git rebasebırakmaya reverttaahhüt. daha önce olduğu gibi çekme isteği gönderin.


1

"Geri döndürme" fikrinden hoşlanmıyorsanız (özellikle bu, birçok işlem için geçmiş bilgilerinin kaybedilmesi anlamına gelirse), her zaman "Hatalı birleştirmeyi geri alma" hakkındaki git belgelerine gidebilirsiniz .

Aşağıdaki başlangıç ​​durumu göz önüne alındığında

 P---o---o---M---x---x---W---x
  \         /
   A---B---C----------------D---E   <-- fixed-up topic branch

(W, M birleşimine ilk dönüşünüzdür; D ve E, başlangıçta kırık özellik dalınıza / taahhüdünüze yönelik düzeltmelerdir)

Artık A'dan E'ye kadar olan komisyonları tekrar oynayabilirsiniz, böylece hiçbiri geri döndürülen birleştirmeye "ait değildir":

$ git checkout E
$ git rebase --no-ff P

Şubenizin yeni kopyası artık mastertekrar birleştirilebilir :

   A'---B'---C'------------D'---E'  <-- recreated topic branch
  /
 P---o---o---M---x---x---W---x
  \         /
   A---B---C----------------D---E

İyi fikir ve doc bağlantısı için teşekkürler. Genelde tekrar birleşmeden önce ustayla yeniden taban kuruyoruz, ancak git daha sonra A ', B', C 'nin öncekilerle aynı olduğunu fark ediyor gibi görünüyor ve şimdi W'dan sonra D, E'ye sahibiz ( pastebin ). Bunun nasıl çözüleceğine dair öneriler?
Kristoffer Bakkejord

0

Bir taahhüdün ardından geri döndürülen ve gönderilmeyen değişikliklerin geri alınması için:

git reset HEAD@{1}

Tüm işaretlenmemiş silmeleri kurtarmak için:

git ls-files -d | xargs git checkout --
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.