Bir şubeden diğerine taahhütleri nasıl kopyalayabilirim?


728

Ustamdan iki şubem var:

  • v2.1 : (sürüm 2) Birkaç aydır çalışıyorum
  • wss : dün efendime belirli bir özellik eklemek için yarattığım (üretimde)

Dünkü taahhütleri wss'den v2.1'e kopyalamanın bir yolu var mı?


Taahhütleri (veya bir dizi taahhüdü) bir şubeden diğerine kopyalamak için bu cevap bana en iyi yardımcı oldu: stackoverflow.com/questions/1994463/…
caramba

Yanıtlar:


565

Bunu birleştirerek gerçekten yapmanıza izin veren bir iş akışınız olmalıdır:

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (wss)

Tek yapmanız gereken git checkout v2.1ve git merge wss. Herhangi bir nedenle bunu gerçekten yapamazsanız ve wss şubenizi doğru yere taşımak için git rebase'i kullanamazsanız , bir yerden tek bir taahhüt alma ve başka bir yere uygulama komutu git cherry-pick'tur . Sadece uygulamak istediğiniz dalı kontrol edin ve çalıştırın git cherry-pick <SHA of commit to cherry-pick>.

Rebase'nin sizi kurtarabileceği yollardan bazıları:

Geçmişiniz şöyle görünüyorsa:

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (v2-only) - x - x - x (wss)

git rebase --onto v2 v2-only wssWss'yi doğrudan v2'ye taşımak için kullanabilirsiniz :

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - x - x (v2-only)
           \
             x - x - x (wss)

Sonra birleştirebilirsiniz! Gerçekten, gerçekten, gerçekten birleştirebileceğiniz noktaya ulaşamazsanız, aynı anda birkaç kiraz seçmeyi etkili bir şekilde yapmak için rebase'i kullanabilirsiniz:

# wss-starting-point is the SHA1/branch immediately before the first commit to rebase
git branch wss-to-rebase wss
git rebase --onto v2.1 wss-starting-point wss-to-rebase
git checkout v2.1
git merge wss-to-rebase

Not: Bunu yapmak için fazladan çalışma gerektirmesinin nedeni, deponuzda yinelenen taahhütler oluşturmasıdır. Bu gerçekten iyi bir şey değil - kolay dallanma ve birleştirmenin tüm amacı, taahhütleri tek bir yer haline getirerek ve ihtiyaç duydukları yerde birleştirerek her şeyi yapabilmektir. Yinelenen taahhütler, bu iki dalı asla birleştirmeyecek bir niyet anlamına gelir (daha sonra yapmak istediğinize karar verirseniz çatışma yaşarsınız).


1
Bu cevapla daha fazla anlaşamadık. +1. Ayrıca, kiraz toplamanın sonuçlarını gösteren eski cevabım: stackoverflow.com/questions/881092/…
VonC

18
Bunun doğru şekilde nasıl yapılacağına dair mükemmel cevap ! Keşke ASCII diyagramları oluşturma çabası için iki kez oylama yapabilseydim.
Mart'ta Gotgenes

@VonC: Desteğiniz için teşekkürler ve neden kiraz almayacağınıza dair ekstra bilgi - Biraz orada eksik olduğumu biliyorum. @gotgenes: Teşekkürler! Bence bu tamamen çabaya değer - sadece git-rebase man sayfasına bakın. Bunu açıklamanın daha iyi bir yolu yok.
Cascabel

Neden birleştirilemediğine gelince - Git birleşmesi git-svn ile iyi oynamıyor. Bir SVN kolundan diğerine bir dizi taahhüt kopyalamak için, kirazları topladım ve sonra tekrar git-svn-idgirmeden önce yanlış referansları kaldırmak için etkileşimli bir rebase / reword gerçekleştirdim dcommit. Gerçi kiraz toplama adımını dışarıda bırakmış ve tek başına bir rebase kullanmış olabilirdim.
Bob

1
İşte benim kullanım durumum: kritik hata düzeltmeleri özellik dalı taahhüt edildi. Şimdi üretime geçmek için ustaca ihtiyacım var. Bu popomu kurtaracak.
Kaptan Hypertext

910

kullanım

git cherry-pick <commit>

mevcut şubenize başvurmak <commit>için .

Kendim muhtemelen seçtiğim taahhütleri çapraz kontrol edip gitkyerine taahhüt girişine sağ tıklamayla vişne seçerdim.


Daha otomatik gitmek istiyorsanız (tüm tehlikeleriyle) ve dünden beri tüm taahhütleri varsayarsak wss'de taahhütlerin listesini oluşturabilirsiniz git log( --prettyJefromi tarafından önerilen)

git log --reverse --since=yesterday --pretty=%H

yani her şeyi birlikte kullandığınız varsayılarak bash

for commit in $(git log --reverse --since=yesterday --pretty=%H);
do
    git cherry-pick $commit
done

Burada bir şeyler ters giderse (çok fazla potansiyel var) bu canlı ödeme işleminde çalıştığından beladasınız, bu yüzden manuel kiraz seçimleri yapın veya Jefromi tarafından önerilen gibi rebase kullanın.


--Pretty seçeneği için tüm yer tutucular git-log kılavuzundadır. İstediğiniz herhangi bir formatı alabilirsiniz - özellikle komut dosyası için istediğiniz alanları kolayca ayrıştırılabilir bir biçimde almak için yararlıdır.
Cascabel

Ayrıca, gerçekten yinelenen taahhütler oluşturmak istediğinizi varsayarsak, cevabımda kullanılan yöntemin git rebasedaha sağlam olduğunu belirtmek isterim. Özellikle, böyle bir for döngüsü kullanmak, kiraz seçimlerinden biri başarısız olursa, yine de geri kalanını yapmaya çalışacaktır. Bu ... çok çok iyi değil, diyelim.
Cascabel

2
Kabul. Bu yüzden hiç kullanmıyorum, ama elle yapıyorum. Ama kiraz toplama hala en azından soru başlığı için cevap. Cevabı değiştirdim.
Benjamin Bannier

1
Birisi eski / yanlış bir şubeye bağlı kaldı ve kiraz toplama, bu taahhüdü doğru şubeye koymama izin verdi (yine de tacı olarak tutuyor). Mükemmel.
Patrick

8
Nadir bir manzara, gitcevabın ne kadar iyi bildiğini kanıtlamak için git'in karmaşıklıklarını dolamak yerine basit ve doğrudan çözüme yönelik bir cevap.
Przemek D

74

git cherry-pick : Mevcut bazı taahhütlerin getirdiği değişiklikleri uygulayın

Varsayalım ki (X, Y, Z) taahhütleri olan A dalımız var. Bu taahhütleri B şubesine eklememiz gerekiyor . cherry-pickOperasyonları kullanacağız .

Kullandığımızda cherry-pick, B şubesine taahhütlerin A Şubesinde göründüğü kronolojik sırada eklemeliyiz .

cherry-pick bir dizi taahhüdü destekler, ancak bu aralıkta birleştirme taahhütleriniz varsa, gerçekten karmaşıklaşır

git checkout B
git cherry-pick SHA-COMMIT-X
git cherry-pick SHA-COMMIT-Y
git cherry-pick SHA-COMMIT-Z

İş akışı örneği:

resim açıklamasını buraya girin

Seçeneklerlecherry-pick birlikte kullanabiliriz

-e veya --edit : Bu seçenekle git cherry-pick taahhütte bulunmadan önce tamamlama mesajını düzenlemenizi sağlar.

-n veya --no-commit : Genellikle komut otomatik olarak bir dizi işlem gerçekleştirir. Bu bayrak, herhangi bir taahhütte bulunmadan çalışma ağacınıza ve dizine adlandırılmış her bir taahhüdü kiraz seçmek için gerekli değişiklikleri uygular. Ayrıca, bu seçenek kullanıldığında, dizininizin HEAD taahhüdüyle eşleşmesi gerekmez. Kiraz toplama endeksinizin başlangıç ​​durumuna karşı yapılır.

İlginç bir Buraya yazı ile ilgili cherry-pick.


19

Sen olabilir bir yama oluşturmak kopyalayıp istediğiniz kaydedilmesini gelen yama uygulamak hedef dalına.


16
Herhangi bir nedenden ötürü kiraz toplama (lar) / rebase yerine yama (lar) kullanmak isteseniz bile, bunu yapmanın en kolay yolu git format-patch <revision range>ve git am *.patch.
Cascabel

checkoutBaşka bir dal gerektiriyor .
CoolMind

12

Veya evangelist tarafında biraz daha az iseniz, kullandığım biraz çirkin bir şekilde yapabilirsiniz. Deploy_template'te, şube konuşlandırması olarak yöneticime kopyalamak istediğim taahhütler var

git branch deploy deploy_template
git checkout deploy
git rebase master

Bu, deploy_template üzerinde yeni şube dağıtımı (varolan konuşlandırma dalının üzerine yazmak için -f kullanıyorum) oluşturur, ardından bu yeni dalı master üzerine yeniden oluşturur ve deploy_template'e dokunulmaz.


1

Sadece son taahhüdü wss şubesinden v2.1'e kopyalamanın basit bir örneği için, yalnızca taahhüt kimliğini ( git log --oneline | head -n 1) alabilir ve şunları yapabilirsiniz:

git checkout v2.1
git merge <commit>

Bunun için başka bir şubeye gitmeniz gerekir.
CoolMind

1

Cherry-pick komutu standart girişten taahhütlerin listesini okuyabilir.

Aşağıdaki komut "kiraz" seçtikleri John kullanıcı tarafından yazılır "geliştirme" dalında var ama "sürüm" dalında değil, ve bunu kronolojik sırada yapar.

git log develop --not release --format=%H --reverse --author John | git cherry-pick --stdin
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.