Farklı bir ad ve yola sahip bir dosyaya Git yaması nasıl uygulanır?


105

İki depom var. Birinde dosyada değişiklik yapıyorum ./hello.test. Değişiklikleri uyguluyorum ve bu taahhütle bir yama oluşturuyorum git format-patch -1 HEAD. Şimdi, hello.test aynı içeriği var ama farklı bir isim altında farklı bir dizinde yerleştirilir bir dosyayı içeren ikinci bir depo vardır: ./blue/red/hi.test. Yukarıda belirtilen yamayı hi.testdosyaya uygulamaya nasıl başlayabilirim ? Denedim git am --directory='blue/red' < patch_fileama bu tabii ki dosyaların isimlerinin aynı olmadığından şikayet ediyor (Git'in umursamadığını düşündüm?). Muhtemelen bu belirli dosyaya uygulamak için farkı düzenleyebileceğimi biliyorum, ancak bir komut çözümü arıyorum.


Yanıtlar:


102

Yamayı kullanarak oluşturabilir git diffve ardından patchdiff'i uygulamak istediğiniz dosyayı belirtmenize olanak tanıyan yardımcı programı kullanarak uygulayabilirsiniz.

Örneğin:

cd first-repo
git diff HEAD^ -- hello.test > ~/patch_file

cd ../second-repo
patch -p1 blue/red/hi.test ~/patch_file

7
Ah, güzel, bunu düşünmedim. Ancak bunu Git komutlarıyla yapmanın herhangi bir yolu var mı, böylece commit verileri (tarih ve saat, commit yazar, commit mesajı) aynı tutulur mu?
mart1n

2
amVeya ile yapabileceğiniz bir şey olabilir apply, ancak bulamıyorum. Kendinizi değişiklikleri çok fazla kopyalarken bulursanız, alt modülleri kullanarak daha iyi bir çözüm olabilir veya kodu paylaşmak için seçtiğiniz dil ne olursa olsun (örneğin Ruby'de yinelenen kodu bir mücevher olarak çıkarabilirsiniz).
georgebrock

1
Bu aslında dokümantasyonla ilgilidir (kaynak dosyalar XML'lerdir). Alt modüller gerçekten bir seçenek değil, çünkü mevcut altyapımızda onlar için güçlü bir örnek oluşturmam gerekiyor.
mart1n

55

Manuel yama düzenleme veya harici komut dosyası içermeyen basit bir çözüm var.

İlk depoda (bu aynı zamanda bir dizi yürütmeyi dışa aktarabilir, -1yalnızca bir kaydetme seçmek istiyorsanız kullanın):

git format-patch --relative <committish> --stdout > ~/patch

İkinci depoda:

git am --directory blue/red/ ~/patch

Bunun yerine kullanmanın --relativeiçinde git format-patch, başka bir çözüm kullanmaktır -p<n>seçeneği git amşeridi için nbir belirtildiği gibi, yamaların yolundan dizinleri benzer bir sorunun cevabı .

Ayrıca, git format-patch --relative <committish>olmadan çalıştırmak da mümkündür --stdoutve bir dizi .patchdosya oluşturur. Bu dosyalar daha sonra doğrudan git amile beslenebilir git am --directory blue/red/ path/to/*.patch.


9
Bu hala dosya adlarının aynı olmasına dayanıyor, değil mi?
mart1n

3
Bu --directoryseçeneğin, repo köküne göre dizinin tam yolunu belirtmenizi gerektirdiği unutulmamalıdır ; --directory=./depodaki bir alt dizine chdir'd iken gibi bir şey çalışmayacaktır.
Reid

1
Kullanımı --3wayyardımcı olur does not exist in index:git am --3way --directory (relative-path) (patch)
Brent Bradburn

-kKaydetme mesajının ilk satırını çıkarmamak için her iki komutta da tuşunu kullanın .
ruvim

Kullanımı --3wayyalnızca "dizinde yok" hatalarına yardımcı olmakla kalmaz (@nobar tarafından belirtildiği gibi), aynı zamanda birleştirme çakışmalarını temiz bir şekilde ele almanıza da olanak tanır. Çakışan dosyaları el değmeden bırakmak yerine, daha sonra çözülebilecek bir çakışma bloğu eklenir.
Daniel Wolf


5

@Georgebrock'un cevabına dayanarak, işte kullandığım bir çözüm:

İlk olarak, yama dosyalarını her zamanki gibi oluşturun (örn. git format-patch commitA..commitB).

Ardından hedef deponuzun temiz olduğundan emin olun (değiştirilmiş veya izlenmemiş dosya olmamalıdır) ve aşağıdaki gibi yamaları uygulayın:

cd second-repo
git am ~/00*.patch

Her yama dosyası için "hata: XYZ dizinde mevcut değil" gibi bir hata alacaksınız. Artık bu yama dosyasını manuel olarak uygulayabilirsiniz:

patch --directory blue/red < ~/0001-*.patch
git add -a
git am --continue

Her yama dosyası için bu üç adımı uygulamanız gerekir.

Bu, herhangi bir özel git format-patchkomut gerektirmeden veya yama dosyalarını düzenlemeden orijinal commit mesajını vb . Koruyacaktır.


1
İyi yanıt, bence bu, her türlü "standart dışı" yama manipülasyonu için en iyi temeldir. 3 adımda yaparım. (1) Metne taahhüt - git format-patch -1 commitA --stdout > thing.diff; (2) İhtiyacım olanı yapana kadar yama dosyasını düzenleyin ; (3) git am --3way thing.diff Yamanın temiz bir şekilde uygulanan kısımlarını kabul etme ve gituymayan kısımlar için standart çakışma çözme sürecini kullanma avantajına sahip olan gerçekleştirilecek metin .
We Are All Monica

2

Sizin durumunuzda iki dosyanın tamamen aynı olduğunu anlıyorum, bu nedenle yama büyük olasılıkla başarılı olacaktır.

Bununla birlikte, benzer ancak tam olarak aynı dosyaya bir yama uygulamak istemeniz veya etkileşimli bir yama yapmak istemeniz durumunda, üç yollu birleştirme kullanacaksınız.

Eğer Dosya modifiye Say A, diyelim belirtmek A~1önceki versiyonu olarak ve aralarında diff uygulamak istediğiniz A~1için ADosya B.

Üç yollu birleştirme aracı açın, örneğin Karşılaştırmanın Ötesinde, sol panelin yolu A, orta panel ortak atadır, bu nedenle A~1yol, sağ panelin yoludur B. Daha sonra, alt panel Şekil arasında yama uygulanarak sonucu A~1için ADosya B.

Aşağıdaki şekil fikri göstermektedir.

görüntü açıklamasını buraya girin


0

Bilginize: Son zamanlarda Github'dan bir yama indirmeye ve bunu yerel bir dosyaya uygulamaya çalışırken sorunlar yaşadım (yeni bir konumda "geçersiz kılma" idi).

git amdosya "dizinde olmadığı" veya "kirli" olduğu için yamayı uygulamaz. Ama, ben basit bulundu patchkomut verebilir yamayı uygulayın. Yamalı dosyanın adını sordu.

İşi hallettim, neyse ...

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.