Git diff - ชื่อเท่านั้นและคัดลอกรายการนั้น


151

ฉันแค่ต้องการได้รับรายชื่อของไฟล์ที่ถูกเปลี่ยนระหว่างการแก้ไขสองครั้งซึ่งง่ายมาก:

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

แต่สิ่งที่ฉันควรเขียนถ้าฉันต้องการคัดลอกไฟล์ทั้งหมดที่ระบุไว้ไปยังที่อื่น? และฉันต้องการโครงสร้างไดเรกทอรีที่เหมือนกันอย่างสมบูรณ์สำหรับไฟล์ที่คัดลอก

ตัวอย่างเช่นฉันได้แก้ไขและเพิ่มไฟล์:

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

ฉันต้องการที่จะมีใน/home/changes/ทุกการเปลี่ยนแปลงและเพิ่มไฟล์:

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

1
ฉันไม่เข้าใจสิ่งที่คุณพยายามที่จะบรรลุ ... เผยแพร่การเปลี่ยนแปลงของโคลนต่าง ๆ ? สร้างแพทช์? กำลังแก้ไขไฟล์นอกที่เก็บ git หรือไม่?
knittl

ไม่ใช่ patch แต่เป็นโครงสร้างการคัดลอกที่แน่นอนของไฟล์ที่เปลี่ยนแปลง เช่นเดียวกับแพทช์ แต่มีไฟล์ทึบ
BazZy

และใช่ปะไฟล์นอกเก็บคอมไพล์ - เป้าหมายใกล้เคียงที่สุดสำหรับฉัน :)
BazZy

3
ขอโทษ อะไร? คุณต้องการที่จะจับภาพและเล่นซ้ำการเปลี่ยนแปลงไฟล์และการเปลี่ยนแปลงต้นไม้? นั่นคือแพทช์ git format-patchสามารถทำสิ่งนี้เพื่อกระทำช่วง
knittl

1
git diff commit1 commit2 > my.patchcd other/path; patch -p1 < my.patchแล้วก็ ทำไมต้องทำกับไฟล์ทั้งหมด? ถ้าเป็นเพราะคุณคิดว่าแพตช์อาจใช้ไม่ได้ดังนั้นไดเรกทอรีอื่น ๆ ไม่ได้อยู่ในcommit1สถานะจริง ๆ คุณควรคัดลอกทุกอย่างจากcommit2รัฐ ...
Cascabel

คำตอบ:


118

ลองคำสั่งต่อไปนี้ซึ่งฉันได้ทดสอบ:

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

2
ขอบคุณสำหรับcp --parentsคำใบ้ฉันต้องการตัวเลือกนั้นมาหลายปีและไม่เคยรู้มาก่อน! .. เห็นได้ชัดว่าฉันไม่เคยสนใจที่จะมองหามันอย่างใดอย่างหนึ่ง = \
เตฟาน Henningsen

2
โปรดทราบว่าวิธีนี้ใช้ไม่ได้กับ Mac เนื่องจากไม่มี--parentsตัวเลือกcpให้
M. Justin

มีคำแนะนำในการใช้อย่างไรถ้าไฟล์มีอักขระที่ผิดปกติ ช่องว่างอักขระนอร์ดิก
Halvor Holsten Strand

@ HalvorStrand ฉันยังไม่ได้ทดสอบ แต่การตั้งค่าIFS=$'\n'ครั้งแรกอาจทำได้ (ควรอยู่ใน subshell เพื่อไม่ให้สับสนกับค่า IFS ดั้งเดิมของคุณ)
Wildcard

ฉันได้รับข้อผิดพลาดcp: cannot stat 'git diff --name-only': No such file or directoryในการทุบตี git บน windows ผมทำอะไรผิดหรือเปล่า? มีไดเรกทอรีปลายทางอยู่
Shiva

14

ต่อไปนี้ควรทำงานได้ดี:

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

เพื่ออธิบายเพิ่มเติม:

  • การ-zถึงด้วยgit diff --name-onlyเพื่อส่งออกรายการไฟล์ที่คั่นด้วย NUL ไบต์แทนการขึ้นบรรทัดใหม่ในกรณีที่ชื่อไฟล์ของคุณมีอักขระที่ผิดปกติ

  • การที่-0จะxargsพูดเพื่อตีความอินพุตมาตรฐานเป็นรายการพารามิเตอร์ที่คั่นด้วย NUL

  • ที่-IREPLACEจำเป็นเนื่องจากโดยค่าเริ่มต้นxargsจะผนวกพารามิเตอร์ต่อท้ายrsyncคำสั่ง แต่ที่บอกว่าจะนำพวกเขาที่ต่อมาREPLACEคือ (นั่นเป็นเคล็ดลับที่ดีจากคำตอบข้อผิดพลาดเซิร์ฟเวอร์นี้)

  • -aพารามิเตอร์rsyncหมายถึงการรักษาสิทธิ์ความเป็นเจ้าของ ฯลฯ ถ้าเป็นไปได้ -Rวิธีการที่จะใช้เส้นทางสัมพัทธ์เต็มรูปแบบเมื่อมีการสร้างไฟล์ในปลายทาง

อัพเดท:ถ้าคุณมีรุ่นเก่าของxargsคุณจะต้องใช้ตัวเลือกแทน-i -I(อดีตถูกคัดค้านในรุ่นที่ใหม่กว่าfindutils)


มันแปลกมาก - คุณใช้ระบบปฏิบัติการอะไร? ถ้าเป็นการกระจายของลีนุกซ์, อันไหน, และมันxargs --versionพูดว่าอะไร
Mark Longair

1
อ้าในรุ่น xargs นั้นคุณจำเป็นต้องใช้-iแทนซึ่งเลิกใช้แล้วในเวอร์ชันที่ใหม่กว่า - 4.1 ค่อนข้างเก่าแล้ว ฉันจะอัปเดตคำตอบของฉัน
Mark Longair

@ Mark: ฉันจำได้ว่าอ่านบางที่ที่คุณต้องการช่องว่างหลังจาก-Iในบางรุ่นดังนั้นอาจลอง-I REPLACEแทน
Mikel

ไม่เป็นไร. ไม่ได้ผลเช่นกัน -Iได้รับการสนับสนุนตั้งแต่findutils4.2.10 เปิดตัวในเดือนธันวาคม 2547
Mikel

คุณควรเพิ่ม--diff-filter=dเพื่อแยกไฟล์ที่ถูกลบออกจากรายการ มิฉะนั้นคุณจะได้รับข้อผิดพลาดในขณะที่พยายามคัดลอกลงในโฟลเดอร์การเปลี่ยนแปลง คำตอบที่ดีเป็นอย่างอื่น ขอบคุณ!
taymless

11

นี่คือหนึ่งซับ:

รายการไฟล์ที่เปลี่ยนแปลงและแพ็คเป็น * .zip:

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

แสดงรายการไฟล์ที่มีการเปลี่ยนแปลงล่าสุดและแพ็คเป็น * .zip:

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

หากคุณใช้ windows คุณสามารถดาวน์โหลด commandline zip ได้จากsourceforge.net/projects/gnuwin32/files/zip
Radon8472

@ Radon8472 นั่นติดตั้งsed.exe? ฉันยังzipไม่พบบน windows
พระอิศวร

ไม่ลิงก์กำลังชี้ไปที่การดาวน์โหลดสำหรับ zip.exe ไม่ใช่เพื่อ sed หากคุณไม่สามารถใช้ zip ใน commandline คุณควรเพิ่มโฟลเดอร์ที่ติดตั้ง zip.exe ไว้ในPATHตัวแปร env ของคุณ
Radon8472



2

มันทำงานได้อย่างสมบูรณ์

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

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

1

ไม่มีใครพูดถึงcpioซึ่งง่ายต่อการพิมพ์สร้างการเชื่อมโยงอย่างหนักและจัดการช่องว่างในชื่อไฟล์:

git diff --name-only $from..$to  | cpio -pld outdir
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.