Git'te başka bir şubeye dayalı olarak belirli taahhütler nasıl taşınır?


381

Durum:

  • master X konumunda
  • quickfix1 X + 2 işleminde

Öyle ki:

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)

Sonra quickfix2 üzerinde çalışmaya başladım, ama yanlışlıkla master değil kopyalanacak kaynak dalı olarak quickfix1'i aldım. Şimdi quickfix2 X + 2 işleminde + 2 ilgili işlemde.

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

Şimdi quickfix2 ile bir şube istiyorum, ama quickfix1 ait 2 taahhüt olmadan.

      q2a'--q2b' (quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

Quickfix2'de belirli bir revizyondan bir yama oluşturmaya çalıştım, ancak yama, taahhüt geçmişini korumuyor. İşlem geçmişimi kaydetmenin bir yolu var, ancak quickfix1'de değişiklik yapılmayan bir şube var mı?



8
@Kevin Bu soru sadece taahhütleri bir şubeden diğerine taşımayı soruyor, bunun da taahhütleri dahil etmeme ek şartı var quickfix1. (Cevaplardaki farkı da not edin.)
Scott Weldon,

Yanıtlar:


372

Bu klasik bir durum rebase --onto:

 # let's go to current master (X, where quickfix2 should begin)
 git checkout master

 # replay every commit *after* quickfix1 up to quickfix2 HEAD.
 git rebase --onto master quickfix1 quickfix2 

Yani gitmelisin

o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

için:

      q2a'--q2b' (new quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

Bu en iyi temiz çalışan bir ağaçta yapılır.
Bkzgit config --global rebase.autostash true . Özellikle Git 2.10'dan sonra .


24
Bu adımların quickfix2'nin geçmişini değiştireceğine dikkat edin, bu nedenle şubeyi daha önce paylaştıysanız, bunun yerine kiraz toplama özelliğini kullanın (aşağıdaki yanıtlara bakın).
Max Chernyak

Sadece kayıtlar için: SmartGit log sadece sürükle q2aüzerine Xbasıp Rebase 2 kaydedilmesini meydana gelen diyalog seçenekler arasından.
Thomas S.

1
@ThomasS. İlginç. Bu güzel bir GUI uygulamasıdır git rebase --onto.
VonC

1
İtiraf etmeliyim ki, yanlış şubeye gerçekten daha sık taahhüt etmek gibi aptalca şeyler yapıyorum, SmartGit günlük görünümü GUI aynı durumla beni birçok kez kurtardı.
WORMSS

1
@Cosine Kabul Edildi. Cevabımı rebase.autostashyapılandırmaya referans eklemek için düzenledim : bu, bir rebase yaparken çalışma ağacında devam eden çalışma kaybını önleyecektir.
VonC

155

git cherry-pickSadece kopyalamak istediğiniz taahhüdü seçmek için kullanabilirsiniz .

Muhtemelen en iyi yol dalı master dışında oluşturmaktır, daha sonra bu branşta kullanmak git cherry-pickistediğiniz quickfix2'den 2 taahhütte kullanmaktır .


Sadece bir taahhüdü taşımak istiyorsanız bu da en iyi seçenektir. Teşekkürler.
Alex

142

Yapabileceğiniz en basit şey, kiraz bir dizi seçmek. Aynı şeyi yapar, rebase --ontoancak gözler için daha kolaydır :)

git cherry-pick quickfix1..quickfix2

6
Ayrıca, orijinal taahhütleri, IIUC kaybetmez, bu yüzden benim gibi "oyun-kasaları" için tercih gibi görünüyor;) veya rebase --ontoorijinal değişiklikleri koruyor mu?
akavel

6
hem rebaseve cherry-picksize yeni SHA anahtarları ver. Çünkü her taahhüt havuzun benzersiz bir anlık görüntüsüdür.
Christoph

6
@Akavel'in kastettiği şey, kiraz toplama işleminin orijinal taahhütlerini şubelerinde tutacağı doğru
Mr_and_Mrs_D

4
Ne kadar değerli olursa olsun cherry-pick, bu cevaptaki gibi bir aralığa çalıştım ve depomu karıştırdı. cherry-pickHer taahhüt için ayrı ayrı yapmak zorunda kaldım . (Ve belki de söylemeden geçer, ancak herhangi birinin mücadele cherry-picketmesi durumunda, taahhütlerinizin uygulandığı kronolojik sırada yapmanız gerekir .)
Carmenism

3
git checkoutburada çok önemli. KAFA nedir? :)
Sławomir Lenart

28

İnanıyorum ki:

git checkout master
git checkout -b good_quickfix2
git cherry-pick quickfix2^
git cherry-pick quickfix2

3
cherry-picktaahhüt karmaları ile çalışır, bu yüzden sadece bir yerden bir taahhüt almak ve başka bir yere koymak istiyorsanız bu gitmek için bir yoldur. checkout <branch>Önce doğru dalı yaptığınızdan emin olun .
John Leidegren

-1
// on your branch that holds the commit you want to pass
$ git log
// copy the commit hash found
$ git checkout [branch that will copy the commit]
$ git reset --hard [hash of the commit you want to copy from the other branch]
// remove the [brackets]

Buradaki diğer faydalı komutların açıklaması: Git Rehberi

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.