Git ile kısmen kiraz toplama taahhüdü


501

2 farklı dal üzerinde çalışıyorum: serbest bırakma ve geliştirme .

Hâlâ yayın şubesine bağlı bazı değişiklikleri tekrar geliştirme dalına .

Sorun şu ki, tüm taahhütlere ihtiyacım yok, sadece belirli dosyalarda bazı iri parçalar, bu yüzden basit

git cherry-pick bc66559

hile yapmaz.

Yaptığımda

git show bc66559

Farkı görebiliyorum ama bunu şu andaki çalışma ağacıma uygulamak için iyi bir yol bilmiyorum.

Yanıtlar:


792

Burada isteyeceğiniz temel şey git add -p( -peşanlamlısıdır --patch). Bu, içeriği kontrol etmek için etkileşimli bir yol sağlar, her bir parçanın girip girmeyeceğine karar vermenize ve hatta gerekirse yamayı manuel olarak düzenlemenize izin verir.

Kiraz toplama ile birlikte kullanmak için:

git cherry-pick -n <commit> # get your patch, but don't commit (-n = --no-commit)
git reset                   # unstage the changes from the cherry-picked commit
git add -p                  # make all your choices (add the changes you do want)
git commit                  # make the commit!

(Git-cherry-pick'un bir -no-taahhüt seçeneği olduğunu hatırlattığı için Tim Henigan'a ve sıfırlamanız gerektiğini işaret ettiği için Felix Rabe'ye teşekkürler! , git reset <path>...yalnızca bu dosyaları açmak için kullanabilirsiniz .)

Elbette add -pgerekirse belirli yollar da sağlayabilirsiniz . Eğer bir yama ile başlayan ediyorsanız yerini alabilir cherry-pickile apply.


Gerçekten istiyorsanız git cherry-pick -p <commit>(bu seçenek mevcut değildir),

git checkout -p <commit>

Bu, mevcut taahhüdü belirttiğiniz taahhüde göre farklılaştıracak ve bu farktan öfkeleri ayrı ayrı uygulamanıza izin verecektir. Bu seçenek, çekmekte olduğunuz taahhüt, ilgilenmediğiniz taahhüdün bir kısmında çakışmaları içeriyorsa daha yararlı olabilir. (Bununla birlikte, aşağıdakilerden checkoutfarklıdır cherry-pick: içeriğini tamamen checkoutuygulamaya çalışır , fark Bu, yalnızca bu taahhütten daha fazlasını uygulayabileceğiniz anlamına gelir; bu , istediğinizden daha fazla olabilir.)<commit>cherry-pickcheckout


Aslında, git 1.7.5.4 ile tavsiyelere uyursam, 'git add -p', 'zaten değişiklik yok' diyor çünkü hepsi zaten dizinde. Ben 'git add' önce bir 'git reset HEAD' yapmak gerekir - bazı seçenek ile bu sıfırlama önlemek için herhangi bir yolu?
Felix Rabe

@FelixRabe: Aslında bir noktada olduğu şaşırdım cherry-pick -ngörünüşte vermedi değişiklikleri terk sahnelenen - kongre kesinlikle olduğunu --no-commitseçenekler durdurma doğru değişiklikler sahnelenen tüm yani işlemeden önce. Cevaba sıfırlamayı ekleyeceğim.
Cascabel

1
@Blixt Yani, diğer dalda olan ancak mevcut dalınızda olmayan taahhütler ABCDEF ise, size sadece F'den gelen değişiklikleri git checkout -p <F>almaz , ABCDEF'i bir araya getirir ve istediğiniz parçayı sıralamanızı sağlar . Bunu F'deki değişikliklerin sadece bir kısmına ayırmak bir acıdır. Öte yandan, sadece F'deki değişiklikleri alır - ve bu değişikliklerin bazıları çakışırsa, size nasıl düzgün bir şekilde birleştirileceğini anlamanız için yardımcı olur. git cherry-pick -n <F>
Cascabel

Değişiklik bir dosya ekleme olduğunda bu konuda sorunları vardı. git resetDosyaları sahnelenen kaldıracak ve add -psadece 'eklemek için bir şey' derdi.
Ian Grainger


36

İstediğiniz değişikliklerin, değişiklik yapmak istediğiniz dalın başında olduğunu varsayarsak, git checkout'u kullanın

tek bir dosya için:

git checkout branch_that_has_the_changes_you_want path/to/file.rb

birden fazla dosya için sadece papatya zinciri:

git checkout branch_that_has_the_changes_you_want path/to/file.rb path/to/other_file.rb

5
Bu tüm dosyayı kopyalar: sadece değişiklikleri değil.
Jeremy List

1
Bu cevabın, şimdiye kadarki diğer herhangi bir cevabın olduğu gibi, büyük bir dezavantajı var: Değişimin orijinal yazarını korumuyor, bunun yerine adınız altında taahhüt ediyor. Eğer bir değişiklik iyi ise, birisinin kredisini çalıyorsunuz, eğer bir değişiklik kötü ise, kendinizi ateşe veriyorsunuz. Görünüşe göre git cherry-pick -p'ye sahip olmanın bir yolu yok ve utanç hala orada değil.
pfalcon

15

Bina Mike Monkiewicz da sağlanan sha1 / şubesinden ödeme için tek bir veya daha fazla dosya belirtebilirsiniz cevap.

git checkout -p bc66559 -- path/to/file.java 

Bu, dosyanın geçerli sürümüne uygulamak istediğiniz değişiklikleri etkileşimli olarak seçmenize olanak tanır.


5
Dosyanın geçerli sürümü bu sürümden önemli ölçüde farklıysa bu sorunludur. (Taahhütte görünmeyen) sayısız alakasız değişiklikle karşılaşırsınız. Ayrıca, gerçekten istediğiniz değişiklikler "gizlenmiş bir biçimde" orijinal fark değil, akımın farkı olarak görünebilir. İstediğiniz orijinal farkın çatışması ve düzgün bir şekilde birleştirilmesi mümkündür; burada bu fırsatın olmayacak.
Kaz

1

Komut satırında bir dosya listesi belirtmek ve her şeyi tek bir atom komutunda yapmak istiyorsanız, şunu deneyin:

git apply --3way <(git show -- list-of-files)

--3way: Bir düzeltme eki temiz uygulanmıyorsa Git, çalıştırabilmeniz için bir birleştirme çakışması oluşturur git mergetool. Atlamak Git'in --3waytemiz uygulamayan yamalardan vazgeçmesine neden olur.


0

"Kısmen vişne toplama" dosyalar içinde "bazı değişiklikler seçerken, ancak diğerlerini atayarak" anlamına gelirse, aşağıdakileri getirerek yapılabilir git stash:

  1. Tam kiraz seçimini yapın.
  2. git reset HEAD^ tüm kiraz toplama taahhüdünün tatsız çalışma değişikliklerine dönüştürülmesi
  3. şimdi git stash save --patch : İstenmeyen malzemeyi saklamak için etkileşimli olarak seçin.
  4. Git, saklanan değişiklikleri çalışma kopyanızdan geri alır.
  5. git commit
  6. İstenmeyen değişikliklerin zulası atmak: git stash drop.

İpucu: İstenmeyen değişikliklerin saklanmasına bir ad git stash save --patch junkverirseniz : şimdi (6) 'yı yapmayı unutursanız, daha sonra ne olduğu için zulayı tanıyacaksınız.


Sadece kiraz alırsanız, sıfırlayın ... saklamak için hiçbir şey yapmayacaksınız. Yukarıda belirtildiği gibi, - no-commit ile bir kiraz toplama yapmanız veya bir sıfırlama --hard HEAD ~ yapmanız gerekir. Olumsuz prosedür uyguladığınızı unutmayın (istemediğinizi seçin). Yukarıda kabul edilen çözüm, olumlu ya da olumsuz bir yaklaşıma izin verir.
Pierre-Olivier Vares

0

Kullanım git format-patchparçası dışarı dilim hakkında ve bakım taahhüt git ambaşka dalı uygulamak için

git format-patch <sha> -- path/to/file
git checkout other-branch
git am *.patch
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.