Git-diff'den yama uyumlu bir çıktı alabilir miyim?


160

Çok basit bir yanlış yapıyorum. Ben sıradan bir yama dosyası hazırlamak için çalışıyorum, bu yüzden bazı değişiklikleri yeniden uygulamak:

$ git diff > before
$ git diff something_here > save.patch
$ git checkout . 
$ patch < save.patch
$ git diff > after
$ diff before after
$

İle something_here boş neredeyse çalışır, ancak dosya adları doğru değildir. Sanýrým sadece bir seçeneđim eksik.

Gerçek hayatta, ödeme bittikten sonra birleştirme yapacağım, bu yüzden yama orada başarısız olabilir, ama ne elde ettiğimi görüyorsun.

Yanlış soruyu sorduğum için buradaki hatamı düzenle . Asıl soru şudur: Değişikliklerimi kaydetmek, birleştirme yapmak ve sonra mümkünse değişiklikleri yeniden uygulamak istiyorum? Ben çünkü biraz yanlış anladı sorulan kullanılan bu tip sorunlarla çözmek için yama kullanılarak ve git diffbu beni yapmak istediğini o yıllardan benziyordu.

Charles Bailey'nin yorumu doğru cevaba sahipti. Benim için git-Apply yapılması gereken doğru şey (git-stash ihtiyacımdan daha ağır görünüyor ve yeniden baslamak ve paketler kesinlikle mevcut beceri seviyemin ötesinde.) Charles'ın verdiği cevabı kabul edeceğim (çünkü yorum kabul edemez). Tüm önerileriniz için teşekkürler.

Düzenleme, 6 yıl sonra Konuyu bilen herkesin bildiği gibi, zorluğunu fazla tahmin ettim git stash. Hemen hemen her gün, aşağıdaki sırayı kullanacağım:

$ git stash
$ git merge
$ git stash pop

8
Özellikle kullanmak istediğiniz herhangi bir nedeni var mı patchziyade git apply?
CB Bailey

3
Ve o zaman bile, gerçekten bir şey git stashveya diğer git araçları yerine yamalara ihtiyacınız var mı?
CB Bailey

3
Düzenleme sonrası, bunun git stashyapmaya çalıştığınız şey için en kolay çözüm olduğunu düşünüyorum , ancak işe yarayan birçok yaklaşım var.
CB Bailey

1
@Malvolio: Aslında, yamanızı saklamak için geçici bir dosya adı düşünmenize bile gerek yok.
CB Bailey

4
@Charlse, bazen git deposu olmadan birine yama göndermeniz gerekir. Örneğin git-svn.
Elazar Leibovich

Yanıtlar:


139

Düzeltme ekini kullanmak istiyorsanız, a/ b/git'in varsayılan olarak kullandığı önekleri kaldırmanız gerekir . Bunu seçenekle yapabilirsiniz --no-prefix(bunu yama -pseçeneğiyle de yapabilirsiniz ):

git diff --no-prefix [<other git-diff arguments>]

Bununla birlikte, genellikle düz kullanmak git diffve daha sonra beslemek için çıktıyı kullanmak daha kolaydır git apply.

Çoğu zaman metinsel yamalar kullanmaktan kaçınırım. Genellikle bir veya daha fazla geçici taahhüt, rebase ile birleştirilir git stashve paketlerin yönetimi daha kolaydır.

Kullanım durumunuz için bunun stashen uygun olduğunu düşünüyorum .

# save uncommitted changes
git stash

# do a merge or some other operation
git merge some-branch

# re-apply changes, removing stash if successful
# (you may be asked to resolve conflicts).
git stash pop

7
git diff --no-prefix master > diff.patchve sonragit checkout master patch -p0 < diff.patch
Natim

1
@Natim En üst düzey güvenlik patch --dry-run < diff.patchiçin son komutu vermeden önce kullanmanızı tavsiye ederim .
ᴠɪɴᴄᴇɴᴛ

1
@ ᴠɪɴᴄᴇɴᴛ Bunu yapmanın yararı ne olurdu? Git'i kullandığımız için hiçbir şeyi kaybetmemiz mümkün değil mi?
Natim

1
@Natim Dediğim gibi, sadece nihai güvenlik için, hata durumunda hiçbir şeyi geri almaya gerek yok. Ben de daha genel kullanım durumunda patchgit okuyan (belki tarafından oluşturulan bir yama dosyası kullanarak) dışında kullanmak isteyen insanlar hakkında düşünüyordum diff.
ᴠɪɴᴄᴇɴᴛ

Dahil etmek için yeni senin yama dosyaları Gerekirse ayrıca yama içinde "diff --no-öneki --cached" yer alır. Belki daha iyi bir yol var?
jamshid

219

Sadece kullanın -p1: yine -p0de --no-prefixdurumda kullanmanız gerekir , böylece dışarıda bırakıp --no-prefixkullanabilirsiniz -p1:

$ git diff > save.patch
$ patch -p1 < save.patch

$ git diff --no-prefix > save.patch
$ patch -p0 < save.patch

1
Nedenini merak ediyorsanız , adam onu güzelce özetliyor - kaynak .
tutuDajuju

3
Bu yeniden adlandırmalarla çalışmaz; yok sayan git diffbir satır patchçıkarır. git applygitmek için bir yoldur.
hraban

17

Git diffs dosya yollarının başına ek bir yol parçasına sahiptir. Bu girdiyi, yama ile -p1 belirterek yola çıkarabilirsiniz, şöyle:

patch -p1 < save.patch

10
  1. Geçerli dizinin farkını (işlenmemiş dosyalar dahil) geçerli HEAD'e kaydediyorum.
  2. Daha sonra save.patchdosyayı (ikili dosyalar dahil) herhangi bir yere taşıyabilirsiniz .
  3. Hedef makinenizde yamayı kullanarak git apply <file>

Not: şu anda hazırlanmış dosyaları da farklıdır.

$ git diff --binary --staged HEAD > save.patch
$ git reset --hard
$ <transport it>
$ git apply save.patch

Hahaha. Bu komik. Bu soruyu neredeyse dört yıl önce sordum ve bunu yapma şeklimim gelişti, ancak dün bana bunu nasıl yapacağımı sorsaydın, cevabını verirdim ve bu sorunun cevabından aldığımı söyledim. (Aslında muhtemelen çıplak kullanmak istiyorsunuz git diff > save.patchve git checkout .bunun yerine bir sıfırlamanın, ama evet ...
Malvolio

Oh onun 4 yaşında fark etmedi: P. Btw, sıfırlama sadece işe yaradığını göstermek için .. Ben de git applydevlet ve mevcut son taahhüt işaretçisi ile ilgili fark kullanan veya yapan kimse görmüyorum . Yapmak git diffhiç bir şey yapmadı
Matej

Evet, şimdi nasıl öğrendiğimi merak ediyorum git apply. Asıl mesele git diff(sanırım) kullanmaktan git reset- repo, endeks ve çalışma alanı arasındaki ilişkiler sorun.
Malvolio

8

Geçici yama dosyaları oluşturmaktan kaçınmak için yararlı bir numara:

git diff | patch -p1 -d [dst-dir]

Tam olarak ne istediğimi. Ayrıca saklamak ile mükemmel çalışır! git stash show -p stash@{3} | patch -p1 -d [dst-dir]
dtmland
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.