Çekme isteği ile birleştirme geri alınsın mı?


159

Birisi, almaması gereken bir çekme talebini kabul etti. Şimdi bir grup kırık kod birleştirildi. Bir çekme isteğini nasıl geri alırsınız? Birleştirme işleminden hemen önce taahhüdün değişikliklerini geri alacaktım, ancak bir sürü taahhütte birleştiğini fark ettim. Şimdi birleşmeden günler önce bu kişiden gelen tüm bu taahhütler var. Bunu nasıl geri alırsın?


7
Kabul edilen cevabın tavsiyesine rağmen, repo başkasıyla paylaşılıyorsa LÜTFEN bir havuza zorlamayın. Başkalarının yaptığı işi mahvetme riskiyle karşı karşıyasınız ve GitHub bu çekme talebinin birleştirildiğini göstermeye devam edebilir. Bu soruya verilecek diğer bir cevap, bir çekme talebini geri almanın daha güvenli bir yolunu açıklamaktadır.
alxndr

2
Not: en azından şimdi (Haziran 2014), GitHub, Çekme İsteği web GUI'lerinde "Geri Al" düğmesini önerir. Aşağıdaki cevabımı
VonC

1
Geri döndürme düğmesiyle ilgili sorun, çekme isteğinin tersi olarak yeni bir taahhüt oluşturmasıdır.
FluffySamurai

Yanıtlar:


159

Bir yoktur iyi bir yanıt Sadece bu aşağı adım adım kırabilir gerçi bu soruna.

Bunun gibi en son yukarı akış değişikliklerini almanız ve kontrol etmeniz gerekir, örneğin:

git fetch upstream
git checkout upstream/master -b revert/john/foo_and_bar

İşleme günlüğüne bir göz atarak, buna benzer bir şey bulmalısınız:

commit b76a5f1f5d3b323679e466a1a1d5f93c8828b269
Merge: 9271e6e a507888
Author: Tim Tom <tim@tom.com>
Date:   Mon Apr 29 06:12:38 2013 -0700

    Merge pull request #123 from john/foo_and_bar

    Add foo and bar

commit a507888e9fcc9e08b658c0b25414d1aeb1eef45e
Author: John Doe <john@doe.com>
Date:   Mon Apr 29 12:13:29 2013 +0000

    Add bar

commit 470ee0f407198057d5cb1d6427bb8371eab6157e
Author: John Doe <john@doe.com>
Date:   Mon Apr 29 10:29:10 2013 +0000

    Add foo

Şimdi daha sonra geri dönüş yapabilme özelliğiyle tüm çekme isteğini geri almak istiyorsunuz. Bunu yapmak için, birleştirme taahhüdünün kimliğini almanız gerekir .

Yukarıdaki örnekte birleştirme taahhüdü , "Birleştirilmiş çekme isteği # 123 ..." yazan üst sırada yer almaktadır .

Her iki değişikliği ( "Ekle çubuğu" ve "Foo ekle" ) geri almak için bunu yapın ve daha sonra geri dönüş yapabileceğiniz ve değişikliklerin geçmişini temiz tutabileceğiniz tüm çekme isteğini geri alan bir taahhütle sonuçlanırsınız:

git revert -m 1 b76a5f1f5d3b323679e466a1a1d5f93c8828b269

6
Bu doğru cevap olmalı. Burada git posta listesinden daha fazla ayrıntı için git geri dönme eğilimi adam sayfasında bir referans yoktur kernel.org/pub/software/scm/git/docs/howto/...
Justin hamade

2
Neden git checkout upstream/master -b revert/john/foo_and_bar? tam olarak ne yapıyor?
Magne

4
@Magne - geri dönüşü yapmak için yeni bir dal oluşturuyorsunuz, daha sonra geri dönüşü nerede birleştireceğinizi seçebilirsiniz. Temel olarak sadece şube ile ne yapacağınız üzerinde daha fazla kontrol sağlar. Benim durumumda, geri dönüşü içeren bu "sabit" daldan geliştirme şubemize yeni bir çekme isteği gönderdim, bu da gerekirse yeni çekme isteğimin de geri alınabileceği anlamına geliyor. Bu, yeniden planlanan bir özelliğin ilk taslağını çıkarmaya karar verdiğimiz bir sürüm için yapıldı. Kötü kod yok, sadece bu sürümde gitmiyor.
Daniel Nalbach

3
Bu konuda zor bir ders öğrendim. Geliştirme branşımıza bir özellik ekledik ancak veri sorunları olduğunu fark ettik ve doğrudan geliştirmeye geri döndük. Daha sonra işler düzeltildiğinde, itmeden önce bu özellik ile uyumluluklarını test etmek için bu şubeye daha yeni geliştirme özellikleri eklemek istedik, bu yüzden özellik dalına geri gelişmeyi birleştirdim. Bu, özellik dalında yapılan her değişikliği yazan geri dönüş taahhüdünü de uyguladı. > <
Greg

86

İşlem grafiğinize bakın (gitk veya benzeri bir programla). Çekme talebinden taahhütleri göreceksiniz ve kendi taahhütlerinizi ve bir birleştirme taahhüdünü göreceksiniz (hızlı ileri bir birleştirme değilse). Birleştirme işleminden önce kendi taahhütlerinizin sonunu bulmanız ve şubeyi bu taahhüde sıfırlamanız yeterlidir.

(Şube reflogunuz varsa, birleştirmeden önce taahhüdü bulmak daha da kolay olmalıdır.)


(Yorumlarda daha fazla bilgi aldıktan sonra düzenleyin :)

Tamam, grafiğe bakalım:

ekran görüntüsü 1

Son (en sağdaki) taahhüdün, burada görülen mavi çizgiyi birleştiren çekme talebi ile yanlış birleştirmeniz olduğunu varsayıyorum . Son iyi taahhüdünüz, daha önce siyah çizgide, burada kırmızı ile işaretlenmiş olacak:

resim açıklamasını buraya girin

Bu taahhüdü sıfırlayın ve iyi olmalısınız.

Bu, yerel çalışma kopyanızda bunu yapın (artık gitmeyen şeyler olmadığından emin olduktan sonra, örneğin git stash tarafından):

git checkout master
git reset --hard 7a62674ba3df0853c63539175197a16122a739ef
gitk 

Şimdi gerçekten orada işaretlediğim taahhütte olduğunuzu onaylayın ve atalarında hiçbir şey görmeyeceksiniz.

git push -f origin master

(github uzaktan kumandanız adlandırılmışsa origin- adı değiştirin).

Şimdi her şey github'da da doğru görünmeli. Taahhütler yine de deponuzda olacak, ancak herhangi bir şube tarafından ulaşılamayacak, bu nedenle orada herhangi bir zarar vermemelidir. (Ve elbette hala RogerPaladin'in deposunda olacaklar.)

(Aynı şeyi yapmanın yalnızca Github'a özgü bir web yolu olabilir, ancak Github'a ve onun çekme isteği yönetim sistemine aşina değilim.)

Not başkası zaten yanlış ile ana taahhüt çekti olabilecek, onlar şu anda olduğu gibi daha sonra aynı sorun var ve gerçekten geri katkıda edemez. yeni ana sürümünüzü sıfırlamadan önce.

Bunun olması muhtemelse veya sadece herhangi bir sorundan kaçınmak istiyorsanız , değişiklikleri eski bir işe geri döndürmek yerine yeni bir işlemle geri almak için git revertkomutu kullanın git reset. (Bazı insanlar asla yayınlanan şubelerle sıfırlama yapmamanız gerektiğini düşünür.) Bunun nasıl yapılacağı ile ilgili bu soruya verilen diğer yanıtlara bakın.

Gelecek için:

RogerPaladin'in şubesinin sadece bazı taahhütlerini istiyorsanız, cherry-pickyerine kullanmayı düşünün merge. Ya da ayrı bir şubeye taşımak ve yeni bir çekme isteği göndermek için RogerPaladin ile iletişim kurun.


Ancak birleştirme ve ilk taahhüdü arasında bir ton taahhüt var. Birleştirme taahhüdümüz, kendi taahhütlerimiz ve sonra onun tarafından başka bir taahhütümüz var. Görünüşe göre onun gerçekten eski taahhütlerinde birleşmiş.
Will

Evet, birleştirilmiş taahhüdün atası olan (ve zaten taahhüdünüzün bir atası değil) her şeyde birleşecektir. Bu, sıfırlamanıza engel olmamalıdır - daha sonra bir rebase yapmadıysanız, taahhütler kendiliğinden yeniden sıralanmayacaktır.
Paŭlo Ebermann

1
Evet, şimdi doğru görünüyor ( kendi içine garip birleşme dışında - ama bu ağ grafik yazılımında bir aksaklık olabilir). :-) Yardımcı olabileceğim için memnunum.
Paŭlo Ebermann

6
Birisi kötü taahhütleri çekti ve daha sonra aynı kötü taahhütleri içeren bir çekme isteği göndermek, bu yüzden onlar gizlice ama repo içine bu belki sorunlu düşünüyorum. Kötü taahhütleri tersine çeviren yeni bir taahhüt oluşturmak daha güvenli olmaz mıydı? Bu şekilde, kötü taahhütler diğer kollara / çatallara çekildiyse, diğer dal / çatallara bir başka çekme ile etkin bir şekilde kaldırılacaklar mı? Bunun ne olduğunu, gerçek olarak bu belirten değilim düşünüyorum OP ile aynı konumda olmak ve bir saat harcadığı ya da öylesine benim bu şartlarda doğru olabilir.
Myles McDonnell

4
@ Bu yanıtı kabul etmemeyi önereceğim. Bu henüz itilmemiş kod için iyidir (bu durumda, bu daha alakalı bir SO sorusudur, ancak genel olarak paylaşılan kod için, geçmişi yeniden yazan bir git komutu yaparak (bu durumda reset --hardve bir zorlama Aşağıdaki @errordeveloper tarafından verilen yanıt, herhangi bir tarih yeniden yazma veya zorlama olmadan bunu yapmanın bir yolunu gösterir.
asmeurer

34

Eğer çektiği son şey buysa

git reset --hard HEAD~1

3
Bu talimatı uygularken dikkatli olun, aslında beni bir adım değil, 2 adım geri getirdi.
szeitlin

1
@szeitlin Sizi bir adım değil, 2 adım geri götürmek nasıl olabilir? Bu yorumun 4+ yıl önce bırakıldığını biliyorum, ancak bunun nasıl olabileceğini bir cevap biliyor mu merak ediyorum. Bu benim için çok önemli. Teşekkürler.
Haradzieniec

Şimdi hatırlamıyorum, ancak sıfırlamaya çalıştığımda yeni bir taahhütte bulunsaydım bunun olabileceğini tahmin ediyorum. Endişeleniyorsanız, sadece bir sahte repo ile test ediyorum.
szeitlin

Bu benim için iyi çalıştı. Son zamanlarda birleştirilmiş çekme isteğini sildi. Sonra git reset --hard HEAD~1, ben kullanılan git push origin -fuzaktan depoyu güncellemek için. Ancak dikkatli olun, bunu yapmadan önce dikkatli olun.
Denis Oluka

24

24 Haziran 2014'ten itibaren, bir PR'yi kolayca iptal etmeyi deneyebilirsiniz (Bkz. " Çekme isteğini geri alma "):

Geri Döndür Düğmesine Giriş

Geri Al'ı tıklayarak GitHub'da bir çekme isteğini kolayca geri alabilirsiniz:

https://camo.githubusercontent.com/0d3350caf2bb1cba53123ffeafc00ca702b1b164/68747470733a2f2f6769746875622d696d616765732e73332e616d617a6f6e6177732e636f6d2f68656c702f70756c6c5f72657175657374732f7265766572742d70756c6c2d726571756573742d6c696e6b2e706e67

Geri alınan değişikliklerle yeni bir çekme isteği oluşturmanız istenir:

https://camo.githubusercontent.com/973efae3cc2764fc1353885a6a45b9a518d9b78b/68747470733a2f2f6769746875622d696d616765732e73332e616d617a6f6e6177732e636f6d2f68656c702f70756c6c5f72657175657374732f7265766572742d70756c6c2d726571756573742d6e65772d70722e706e67

Bu geri döndürmenin kullanılıp kullanılmadığı test edilmeye devam eder -m(birleştirmeleri geri almak için de)

Ancak Adil H Raza yorumlara ekliyor (Aralık 2019):

Bu beklenen davranıştır, yeni bir dal yarattı ve bu yeni daldan sizin için bir PR oluşturabilirsiniz master.
Bu şekilde gelecekte geri almayı geri alabilirsiniz, gerekirse en güvenli seçenektir ve doğrudan değiştirmezsiniz master.


Uyarı : Korayem işaret yorumlarda o:

Geri döndükten sonra, Git dalında başka değişiklikler yaptığınızı ve aynı kaynak / hedef daldan yeni bir PR oluşturduğunuzu varsayalım.
Halkla İlişkiler sadece yeni değişiklikler gösteriyor, ancak geri dönmeden önce orada olan hiçbir şey yok .

Korayem bizi daha fazla bilgi için " Github: Gerigit cherry-pickgit rebase döndürüldükten sonra göz ardı edilen değişiklikler ( , ) " olarak adlandırıyor.


Bunu denedim ve master PR geri yerine yeni bir şube yarattı?
Грозный

Garip. Bu davranışı göstermek için yeni bir soru sorabilir misiniz?
VonC

beklenen davranıştır, yeni bir dal oluşturdu ve bu yeni daldan master'ınıza bir PR oluşturabilirsiniz. Bu şekilde gelecekte geri dönüşü gerektiğinde geri alabilirsiniz, en güvenli seçenek ve doğrudan ustanızı değiştirmez.
Adil H. Raza

1
@ AdilH.Raza Teşekkür ederim. Daha fazla görünürlük için yorumunuzu cevaba ekledim.
VonC

1
@VonC parmakları geçti, dünyadaki geliştiricileri çok fazla acı ve zaman
kaybından kurtaracak

8

Silmek istemediğiniz tüm taahhütlerle birlikte bir github çekme isteğini geri almak için aşağıdakileri çalıştırmanız gerekir:

git reset --hard --merge <commit hash>

taahhüt karması çekme talebini birleştirmek için ÖNCEKİ taahhüttür. Bu işlem, tarih içindeki hiçbir taahhüdü etkilemeden çekme talebindeki tüm taahhütleri kaldıracaktır.

Bunu bulmanın iyi bir yolu, şimdi kapalı çekme isteğine gitmek ve bu alanı bulmaktır:

İstek Resmi Çek İstek Resmi Çek

Çalıştırdıktan sonra git reset, aşağıdakileri çalıştırın:

git push origin --force <branch name>

Bu, çekme talebinden gelen taahhütler arasındaki taahhüt geçmişine biberlenmiş daldaki herhangi bir taahhütü etkilemeden şubeyi çekme talebinden önce geri almalıdır.

DÜZENLE:

Çekme isteğinde geri döndür düğmesini tıklarsanız, dalda ek bir taahhüt oluşturulur. Devreden çıkarmaz veya ayırmaz. Bu, geri döndür düğmesine basarsanız, tüm bu kodu tekrar eklemek için yeni bir çekme isteği açamayacağınız anlamına gelir.


Herhangi bir çılgın geri dönüş veya kiraz toplama gerek kalmadan işleri düzeltmek için harika bir yol
Cumulo Nimbus 18:17

Teşekkürler! Yapmayı planladığım şey buydu, ama bu kiraz seçimini yapmak için yaklaşık ~ 200 taahhüt olurdu.
FluffySamurai

1

Bu yeri her zaman kullanıyorum, teşekkürler.

Bir çekme isteğinin nasıl geri alınacağını araştırıyordum ve buraya geldim.

Sadece git reset --hard"uzun zaman önce" ve çekme isteği yapmadan önce bulunduğum yere hızlı bir şekilde geri dönmek üzereydim .

Buraya bakmanın yanı sıra, iş arkadaşıma ne yapacağını da sordum ve tipik olarak iyi bir cevabı vardı: yukarıdaki ilk cevapta örnek çıktıyı kullanarak:

git reset --hard 9271e6e

Git'teki çoğu şeyde olduğu gibi, bunu kolay olmayan bir şekilde yapıyorsanız, muhtemelen yanlış yapıyorsunuzdur.

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.