ฉันจะเห็นภาพความแตกต่างของแต่ละอักขระในไฟล์ diff แบบรวมได้อย่างไร


122

git format-patchบอกว่าผมจะได้รับแพทช์ที่สร้างขึ้นด้วย ไฟล์นี้มีความแตกต่างแบบรวมกับข้อมูลเมตาบางอย่าง ถ้าฉันเปิดไฟล์ใน Vim ฉันจะเห็นว่าบรรทัดใดถูกแก้ไข แต่ฉันไม่เห็นว่าอักขระใดในบรรทัดที่เปลี่ยนแปลงแตกต่างกัน มีใครรู้วิธี (ใน Vim หรือซอฟต์แวร์ฟรีอื่น ๆ ที่ทำงานบน Ubuntu) เพื่อให้เห็นภาพความแตกต่างของแต่ละอักขระหรือไม่?

vimdiff a bตัวอย่างที่เคาน์เตอร์ที่แตกต่างต่อตัวละครคือมองเห็นคือเมื่อการดำเนินการ

อัปเดตศ. 12 พ.ย. 22:36:23 UTC 2010

diffpatch มีประโยชน์สำหรับสถานการณ์ที่คุณกำลังทำงานกับไฟล์เดียว

อัปเดตพฤ. 16 มิ.ย. 17:56:10 UTC 2559

ตรวจสอบdiff ไฮไลท์ในการคอมไพล์ 2.9 สคริปต์นี้ไม่ว่าสิ่งที่ผมเดิมที่กำลังมองหา


สิ่งนี้อาจจะดีกว่าใน superuser.com
Daenyth

13
บางที ฉันเลือก stackoverflow.com เนื่องจากคำถามที่พบบ่อยกล่าวถึงนี่เป็นสถานที่สำหรับคำถามเกี่ยวกับ "เครื่องมือซอฟต์แวร์ที่โปรแกรมเมอร์ใช้กันทั่วไป"
Adam Monsen

7
ฉันไม่แน่ใจว่าสิ่งนี้จะตอบคำถามของคุณโดยตรง แต่git diff --color-wordsมีประโยชน์มากสำหรับการดูว่าคำใดเปลี่ยนแปลงภายในบรรทัดแทนที่จะเป็นผลลัพธ์ที่แตกต่างแบบรวมปกติ แม้ว่าจะเป็นแบบคำมากกว่าตามตัวอักษรดังนั้นหากไม่มีช่องว่างมากนักในเนื้อหาที่คุณแตกต่างผลลัพธ์อาจจะดูเรียบร้อยน้อยกว่า (แก้ไข: อ๊ะฉันเห็นว่าฉันเข้าใจผิดในสิ่งที่คุณขอ - อย่างไรก็ตามความคิดเห็นนี้อาจเป็นประโยชน์กับใครบางคน)
Mark Longair

คำตอบ:


13

จากการอ้างอิงถึง Vim ในคำถามฉันไม่แน่ใจว่านี่เป็นคำตอบที่คุณต้องการหรือไม่ :) แต่ Emacs สามารถทำได้ เปิดไฟล์ที่มี diff ตรวจสอบให้แน่ใจว่าคุณอยู่ในdiff-mode(ถ้าไฟล์เป็นชื่อfoo.diffหรือfoo.patchนี้เกิดขึ้นโดยอัตโนมัติมิฉะนั้นพิมพ์M-x diff-mode RET) ให้ไปก้อนใหญ่ที่คุณสนใจและตีสำหรับC-c C-b refine-hunkหรือก้าวผ่านไฟล์ทีละก้อนด้วยM-n; ซึ่งจะทำการปรับแต่งโดยอัตโนมัติ


1
ใช้ได้ผลสำหรับฉัน! ฉันใช้ Vim มา 10 ปีแล้ว แต่ฉันเพิ่งติดตั้ง emacs :)
Adam Monsen

แต่ emacs ไม่รองรับการอ่านจาก stdin ฉันไม่สามารถทำได้เช่นgit log master.. -p | emacs -
Hi-Angel

1
@ Hi-Angel คุณสามารถเปิด Emacs และพิมพ์M-!เพื่อรันคำสั่งและจับผลลัพธ์ในบัฟเฟอร์
legoscia

172

ในคอมไพล์คุณสามารถรวมได้โดยไม่ต้องกระทำ รวมโปรแกรมแก้ไขของคุณก่อนจากนั้นทำ:

git diff --word-diff-regex=.

สังเกตจุดหลังเครื่องหมายเท่ากับ


139
ดีกว่า: git diff --color-words=..
ntc2

4
@ ntc2 คุณควรแสดงความคิดเห็นเป็นคำตอบ
Tyler Collier

1
ผู้โหวตโปรดทราบกรณีการใช้งานเดิมของฉันถือว่าคุณมีเพียงไฟล์แพทช์ไม่มี git repo หรือแม้แต่เวอร์ชันพื้นฐาน / แก้ไข นั่นเป็นเหตุผลที่ฉันยอมรับคำตอบของ @ legoscia ... มันอธิบายถึงสิ่งที่ร้องขอ
Adam Monsen

2
@ ntc2 git diff --color-words=.และgit diff --color-words .ทำงานแตกต่างกัน git diff --color-words .ที่ดีกว่าคือ
abhisekp

2
@abhisekp: ขอบคุณสำหรับรูป ฉันคิดว่าฉันคิดออกแล้วมันgit diff --color-words .เหมือนกับจริงๆgit diff --color-words -- .! กล่าวคือ.ถูกตีความว่าเป็นเส้นทาง mkdir x y; echo foo > x/test; git add x/test; git commit -m test; echo boo > x/test; cd y; git diff --color-words=.; git diff --color-words .; git diff --color-words -- .คุณสามารถตรวจสอบกับ
ntc2

145

นี่คือบางส่วนรุ่นกับการส่งออกที่มีเสียงดังน้อยกว่าที่มีgit diff --word-diff-regex=<re>และที่จำเป็นต้องมีการพิมพ์น้อยกว่า git diff --color-words --word-diff-regex=<re>แต่จะเทียบเท่ากับ

ง่าย (เน้นการเปลี่ยนแปลงพื้นที่):

git diff --color-words

ง่าย (เน้นการเปลี่ยนแปลงอักขระแต่ละตัวไม่เน้นการเปลี่ยนแปลงช่องว่าง):

git diff --color-words=.

ซับซ้อนมากขึ้น (เน้นการเปลี่ยนแปลงของพื้นที่):

git diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'

โดยทั่วไป:

git diff --color-words=<re>

<re>regexp กำหนด "คำ" อยู่ที่ไหนเพื่อจุดประสงค์ในการระบุการเปลี่ยนแปลง

สิ่งเหล่านี้จะมีเสียงดังน้อยกว่าเนื่องจากใช้สีของ "คำ" ที่เปลี่ยนไปในขณะที่การใช้--word-diff-regex=<re>"คำ" ที่จับคู่กับ-/+เครื่องหมายสี


9
ตัวเองชอบ--color-wordsโดยไม่ต้องมี=.ส่วน
Tyler Collier

1
git diff --color-words='\w'จะทำงานได้ดีกับการกำกับ (คอมไพล์ v1.7.10.4)
NR

1
เวอร์ชันที่ซับซ้อนกว่าของคุณใช้งานได้ดี ผมต่อท้าย--word-diff=plainไปนอกจากนี้ยังมี[-และ-]ลบรอบทิศทาง{+และ+}การเพิ่มรอบทิศทาง ตามที่คู่มือเตือนแม้ว่าการเกิดขึ้นจริงของตัวคั่นเหล่านี้ในแหล่งที่มาจะไม่มีการหลบหนี แต่อย่างใด
Tobias Kienzler

2
เวอร์ชันที่ซับซ้อนกว่าของคุณดูเหมือนจะไม่เน้นเช่นการเปลี่ยนแปลงการเยื้องฉันได้เปิดคำถามเกี่ยวกับเรื่องนี้
Tobias Kienzler

คำตอบนี้ดีมาก! อย่างไรก็ตามมีวิธีเปลี่ยนพื้นหลังของการเปลี่ยนแปลงเหล่านั้นเป็นสีเขียว / แดงได้จริงหรือ?
WoLfPwNeR

45
git diff --color-words="[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+"

regex ข้างต้น ( จาก Thomas Rast ) ทำงานได้ดีในการแยกส่วนที่แตกต่างในระดับเครื่องหมายวรรคตอน / อักขระ (ในขณะที่ไม่มีเสียงดัง--word-diff-regex=.)

ผมโพสต์ภาพหน้าจอของการส่งออกที่เกิดที่นี่


ปรับปรุง:

บทความนี้มีคำแนะนำดีๆ โดยเฉพาะอย่างยิ่งcontrib/โครงสร้างของ git repo มีdiff-highlightสคริปต์ perl ที่แสดงไฮไลต์แบบละเอียด

เริ่มใช้งานอย่างรวดเร็ว:

$ curl https://git.kernel.org/cgit/git/git.git/plain/contrib/diff-highlight/diff-highlight > diff-highlight
$ chmod u+x diff-highlight
$ git diff --color=always HEAD~10 | diff-highlight | less -R

5
คุณสามารถย่อเป็น--color-words=[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'
แก้ไข

ฉันต้องเพิ่ม'จุดเริ่มต้นของค่าตรงนั้น มิฉะนั้นฉันได้รับข้อผิดพลาด นอกจากนี้ฉันเพียงแค่ใช้--color-wordsฉันได้รับพฤติกรรมเดียวกันกับการใช้ regexp นั้น
gcb

3
@gcb เนื้อหาข้อความมีความสำคัญ หากการเปลี่ยนแปลงของคุณถูกคั่นด้วยช่องว่างก็ไม่มีความแตกต่าง แต่ถ้าคุณเปลี่ยนถ้าคุณเปลี่ยนบางอย่างเช่นfoo.barการfoo.quxที่คุณจะเห็นความแตกต่าง
Justin M.Keyes

5
ง่ายกว่า: git diff --color-words='[^[:space:]]|([[:alnum:]]|UTF_8_GUARD)+'.
ntc2

1
ฉันติดตั้งคอมไพล์ด้วย Homebrew และมีสคริปต์นั้นอยู่แล้วที่/usr/local/share/git-core/contrib/diff-highlight/diff-highlight. นี้ดูเหมือนว่าจะชี้ให้เห็นว่าคอมไพล์ Homebrew ของไม่ติดตั้ง contrib /usr/local/share/git-core/contrib/ทั้งใน ในที่สุดสิ่งต่อไปนี้ก็ใช้ได้ผลสำหรับฉันgit diff --color=always | /usr/local/share/git-core/contrib/diff-highlight/diff-highlight
Ashutosh Jindal

6

หากคุณไม่มีอะไรต่อต้านการติดตั้ง NodeJS มีแพ็คเกจที่เรียกว่า "diff-so-fancy" ( https://github.com/so-fancy/diff-so-fancy ) ซึ่งติดตั้งง่ายมากและทำงานได้อย่างสมบูรณ์:

npm install -g diff-so-fancy
git diff --color | diff-so-fancy | less -R

แก้ไข: เพิ่งพบว่าจริงๆแล้วมันเป็นกระดาษห่อหุ้มสำหรับไฮไลต์ที่แตกต่างอย่างเป็นทางการ ... อย่างน้อยก็ง่ายต่อการติดตั้งสำหรับ perlophobes เช่นฉันและหน้า GitHub ได้รับการบันทึกไว้อย่างดี :)


2

ฉันไม่ทราบถึงเครื่องมือความแตกต่างของแต่ละอักขระ แต่มีเครื่องมือสำหรับความแตกต่างของแต่ละคำ: wdiff

ดูตัวอย่างด้านบนเครื่องมือแตกต่าง 4 แฟ้มบน Unix / Linux - Diff, Colordiff, wdiff, vimdiff


wdiff น่าสนใจขอบคุณ! เพื่อชี้แจงคำถามเดิมของฉันฉันกำลังมองหาสิ่งที่ให้การเน้นไวยากรณ์ขั้นสูงสำหรับไฟล์เดียวที่อยู่ในรูปแบบที่แตกต่างกัน
Adam Monsen

offtopic เล็กน้อย (เกี่ยวกับความแตกต่างแบบคำต่อคำไม่ได้เพิ่มเอาต์พุต diff ที่มีมาก่อน) แต่ฉันพบว่าชุดค่าผสมต่อไปนี้ดีที่สุดสำหรับการแสดงภาพแบบคำต่อคำ: * wdiff old_file new_file | cdiff * vimdiff จากนั้นให้อยู่ภายในกลุ่ม:windo wincmd Kเพื่อเปลี่ยนไปใช้เค้าโครงหน้าต่างแนวตั้ง (ด้านล่างอีกด้านหนึ่ง) จากด้านข้าง เค้าโครงนั้นดีกว่ามากสำหรับไฟล์ที่มีเส้นยาว
Aleksander Adamowski

2
BTW บางเครื่องมืออื่น ๆ มูลค่าการตรวจสอบไม่ได้กล่าวถึงในบทความที่เชื่อมโยง: wdiff2, mdiffและเครื่องมือออนไลน์ของ Google
Aleksander Adamowski

1

หลังจากการค้นคว้าเล็กน้อยฉันสังเกตเห็นว่าคำถามนี้เกิดขึ้นสองครั้งเมื่อเร็ว ๆ นี้ในรายชื่อผู้รับจดหมาย Vim หลัก มีการกล่าวถึงปลั๊กอิน NrrwRgn ทั้งสอง ครั้ง (สร้างสองพื้นที่แคบและแตกต่างกัน) การใช้ NrrwRgn ตามที่ Christian Brabandt อธิบายไว้ให้ความรู้สึกเหมือนเป็นวิธีแก้ปัญหามากกว่าวิธีแก้ปัญหา แต่อาจจะดีพอ

ฉันลองใช้ NrrwRgn และร่วมกับ: diff สิ่งนี้มีประโยชน์อย่างแท้จริงสำหรับการแสดงความแตกต่างของแต่ละอักขระภายในส่วนต่างๆของไฟล์เดียว แต่ต้องใช้การกดแป้นพิมพ์หลายครั้ง Vimscript ของฉันค่อนข้างเป็นสนิม แต่อาจเป็นสคริปต์ได้ บางที NrrwRgn อาจได้รับการปรับปรุงเพื่อให้มีฟังก์ชันที่ต้องการ

คิด?

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