Git diff - salt ad ve listeyi kopyala


151

Sadece iki düzeltme arasında değişen dosyaların bir listesini almak istiyorum, bu basit:

git diff -–name-only commit1 commit2 > /path/to/my/file

Ancak, listelenen tüm dosyaları başka bir yere kopyalamak istersem ne yazmalıyım? Ve kopyalanan dosyalar için tamamen aynı dizin yapısına ihtiyacım var.

Örneğin, dosyaları değiştirdim ve ekledim:

/protected/texts/file1.txt
/protected/scripts/index.php
/public/pics/pic1.png

Ben olmasını istediğiniz /home/changes/tüm bu değişti ve eklenen dosyalar:

/home/changes/protected/texts/file1.txt
/home/changes/protected/scripts/index.php
/home/changes/public/pics/pic1.png

1
Neyi başarmaya çalıştığınızı tam olarak anlamıyorum… değişiklikleri farklı klonlara yayarak? yamalar oluşturuluyor mu? bir git deposu dışındaki dosyalar yama?
— knittl

Düzeltme eki değil, değiştirilen dosyaların tam kopya yapısı. Yama gibi, ancak katı dosyalarla
— BazZy

Ve evet, git deposu dışındaki dosyaları düzeltme eki - benim için en yakın hedef :)
— BazZy

3
afedersiniz. NE? dosya ve ağaç değişikliklerini yakalamak ve yeniden oynatmak mı istiyorsunuz? bu bir yama. git format-patchbunu taahhüt aralıkları için yapabilir.
— knittl

1
git diff commit1 commit2 > my.patchve sonra cd other/path; patch -p1 < my.patch. Neden dosyaların tam kopyalarıyla yapılması gerekiyor? Eğer yama geçerli olmayabilir düşünüyorum ve bu nedenle diğer dizin gerçekten değil çünkü öyle olursa commit1devlet, gerçekten kopyalamak gerektiğini şeyi dan commit2... devlet
— Cascabel

Yanıtlar:


118

Test ettiğim şu komutu deneyin:

$ cp -pv --parents $(git diff --name-only) DESTINATION-DIRECTORY

2
cp --parentsİpucu için teşekkürler , bu seçeneği yıllarca istedim ve var olduğunu asla bilmiyordum! Açıkçası ben de aramak için hiç rahatsız etmedim = \
— Stephan Henningsen

2
--parentsSeçeneği cpmevcut olmadığından , bunun Mac'te çalışmadığını unutmayın .
— M. Justin

Dosyaların olağandışı karakterleri varsa bunu kullanmayla ilgili ipucu var mı? Boşluk, nordic karakterler.
— Halvor Holsten Strand

@HalvorStrand, test etmedim, ama IFS=$'\n'ilk olarak ayarlayabilir . (Tercihen orijinal IFS değerinizi bozmamak için bir alt kabukta.)
— Wildcard

cp: cannot stat 'git diff --name-only': No such file or directoryWindows'ta git bash üzerinde bir hata alıyorum . Neyi yanlış yapıyorum? Hedef dizini var
— Shiva

14

Aşağıdakiler iyi çalışmalıdır:

git diff -z --name-only commit1 commit2 | xargs -0 -IREPLACE rsync -aR REPLACE /home/changes/protected/

Daha fazla açıklamak için:

  • -zİle karşı git diff --name-onlyNUL ile ayrılmış dosyaların çıkışına vasıtası listesi dosya adları onlara sıradışı karakterler ihtimale karşı yerine satırsonlarının ait bayt.

  • -0İçin xargsparametrelerin bir boş ayrılmış liste olarak standart girdi yorumlamak söylüyor.

  • -IREPLACEVarsayılan olarak beri gereklidir xargssonuna parametreler ekleyecektir rsynckomuta. Bunun yerine, onları daha sonra REPLACEolduğu yere koymak diyor . (Bu Sunucu Hatası yanıtından güzel bir ipucu .)

  • -aParametre rsyncaracı izinleri, mülkiyeti vb mümkünse korumak için. -RHedef dosya oluştururken araçlar tam göreli yolu kullanmak.

Güncelleme: eski bir sürümüne xargssahipseniz, -ibunun yerine seçeneği kullanmanız gerekir -I. (İlki, sonraki sürümlerinde kullanımdan kaldırılmıştır findutils.)


Bu garip - hangi işletim sistemini kullanıyorsunuz? Bu bir Linux dağıtımı ise hangisi ve ne xargs --versiondiyor?
— Mark Longair

1
Ah, bu xargs sürümünde kullanmanız gerekiyor, -ibunun yerine sonraki sürümlerde kullanımdan kaldırılıyor - 4.1 şimdi oldukça eski. Cevabımı güncelleyeceğim.
— Mark Longair

@Mark: -IBazı versiyonlarda boşluğa ihtiyaç duyduğunuz bir yerde okuduğumu hatırlıyorum , -I REPLACEbunun yerine belki deneyin .
— Mikel

Boşver. Bu da işe yaramıyor. -Iyalnızca findutilsAralık 2004'te yayınlanan 4.2.10'dan beri desteklenmektedir .
— Mikel

--diff-filter=dSilinen dosyaları listeden hariç tutmak için eklemeniz gerekir . Aksi takdirde, bunları değişiklikler klasörüne kopyalamaya çalışırken hatalarla karşılaşırsınız. Aksi takdirde harika bir cevap. Teşekkürler!
— taymless

11

İşte bir astar:

Değiştirilen dosyaları listeleyin ve * .zip olarak paketleyin:

git diff --name-only | zip patched.zip -@

Son kaydedilen değiştirilmiş dosyaları listeleyin ve * .zip olarak paketleyin:

git diff --name-only HEAD~ HEAD | zip patched.zip -@

Windows kullanıyorsanız komut satırı zip dosyasını sourceforge.net/projects/gnuwin32/files/zip adresinden indirebilirsiniz
— Radon8472

@ Radon8472 Yükleniyor sed.exemu? Hala zippencerelerde bulunamıyorum.
— Shiva

Hayır, bağlantı sed için değil zip.exe için indirme işaret ediyor. Komut satırında zip kullanamıyorsanız, zip.exe dosyasının kurulu olduğu klasörü PATHenv değişkeninize eklemelisiniz .
— Radon8472

6
zip update.zip $(git diff --name-only commit commit)


2

Mükemmel çalışıyor.

git diff 1526043 82a4f7d --name-only | xargs zip update.zip

git diff 1526043 82a4f7d --name-only |xargs -n 10 zip update.zip

1

cpioKolay yazılan, sabit bağlantılar oluşturan ve dosya adlarındaki boşlukları işleyen hiç kimse bahsetmedi :

git diff --name-only $from..$to  | cpio -pld outdir
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.