จะแตกต่างคอมมิชชันกับพาเรนต์ได้อย่างไร?


460

นอกเหนือจากการเขียนนามแฝงหรือสคริปต์แล้วยังมีคำสั่งที่สั้นกว่าสำหรับการรับส่วนต่างสำหรับการคอมมิชชันเฉพาะหรือไม่?

git diff 15dc8^..15dc8

หากคุณให้ ID การคอมมิทเพียงครั้งเดียวgit diff 15dc8มันจะแตกต่างที่กระทำกับ HEAD


สิ่งที่ยอดเยี่ยมที่สุดเกี่ยวกับเรื่องนี้ก็คือสิ่งนี้จะใช้ได้กับ "git difftool" โดยใช้เครื่องมือเพื่อแสดงความแตกต่าง
orip

สำหรับการอ้างอิงคำตอบของคำถามนี้แสดงให้เห็นว่าคุณสามารถตั้งค่านามแฝงที่ขับเคลื่อนด้วย bash เพื่อทำให้ง่ายขึ้นได้อย่างไร: stackoverflow.com/questions/3321492/…
Nick

คำตอบ:


641

git show $COMMITใช้ มันจะแสดงข้อความบันทึกการกระทำและส่วนต่างของการส่งข้อมูลนั้น


45
น่าเสียดายที่มันไม่สามารถใช้ difftool :(
orip

1
@ หรือคุณสามารถตั้งค่า GIT_EXTERNAL_DIFF เป็นสคริปต์ที่ทำสิ่งเดียวกันกับ difftool ของคุณ
slacy

7
ฉันชอบคำตอบของ JakubNarebski เนื่องจากสำนวนการกระทำที่ให้ไว้จะทำงานในหลายบริบท: stackoverflow.com/a/449128/992887
RichVel

1
หากไม่แสดงให้เห็นว่ามีความแตกต่างกันอาจจะไม่มีการเปลี่ยนแปลงจริงเช่นการรวมคอมมิชชัน
Devin G Rhode

6
@PTWithy: คำถามคือ "มีคำสั่งที่สั้นกว่าสำหรับการขอคำสั่งที่เฉพาะเจาะจงหรือไม่?" ซึ่งคำถามนี้ตอบ
mipadi

439

ใช้:

git diff 15dc8^!

ตามที่อธิบายไว้ในส่วนต่อไปของgit-rev-parse (1) manpage (หรือในgitrevisions git สมัยใหม่(7) manpage):

ชวเลขอีกสองอันสำหรับตั้งชื่อชุดที่เกิดขึ้นจากการคอมมิชชันและคอมมิทของมันจะมีอยู่ สัญกรณ์ r1 ^ @ หมายถึงผู้ปกครองทั้งหมดของ r1 r1 ^! รวมคอมมิชชัน r1 แต่ไม่รวมพาเรนต์ทั้งหมด

ซึ่งหมายความว่าคุณสามารถใช้15dc8^!เป็นชวเลขสำหรับ15dc8^..15dc8ทุกที่ในคอมไพล์ที่จำเป็นต้องมีการแก้ไข สำหรับคำสั่งdiffgit diff 15dc8^..15dc8นั้นเข้าใจกันgit diff 15dc8^ 15dc8ซึ่งหมายถึงความแตกต่างระหว่าง parent of commit ( 15dc8^) และ commit ( 15dc8)

หมายเหตุ : คำอธิบายในgit-rev-parse(1)manpage พูดถึงช่วงการแก้ไขซึ่งจำเป็นต้องใช้เพื่อรวมการกระทำที่มีผู้ปกครองมากกว่าหนึ่งคน จากนั้นr1^!คือ " r1 --not r1^@" ie " r1 ^r1^1 ^r1^2 ..."


นอกจากนี้คุณสามารถใช้git show COMMITเพื่อรับกระทำคำอธิบายและความแตกต่างสำหรับการกระทำ หากคุณต้องการความแตกต่างเพียงอย่างเดียวคุณสามารถใช้git diff-tree -p COMMIT


7
นี่ควรเป็นคำตอบที่ยอมรับได้มันยอดเยี่ยมมาก อย่างไรก็ตามประโยคสุดท้ายของสารสกัด git-rev-parse ค่อนข้างสับสน - ดูเหมือนว่าหมายถึง 'ช่วงจากพาเรนต์ของคอมมิทนี้ไปยังคอมมิทนี้'
RichVel

1
@RichVel: มันค่อนข้างสับสนเพราะมันพยายามอธิบายสถานการณ์ที่การคอมมิชชันมีพาเรนต์มากกว่าหนึ่งตัว (เป็นการรวมคอมมิชชัน) r1 ^! ทำงานตามที่คาดไว้แล้ว
Jakub Narębski

@ JakubNarębski: จุดที่ดีบางทีคุณสามารถแก้ไขคำตอบของคุณเพื่อสรุปความเข้าใจของคุณในกรณีผู้ปกครองเดี่ยวและหลายผู้ปกครอง - งบแยกในแต่ละอาจจะง่ายต่อการเข้าใจ
RichVel

1
@ JakubNarębski: ใช่ดีกว่ามาก! ตอนนี้ฉันใช้ทางลัดนี้ตลอดเวลา - ขอบคุณ
RichVel

1
^!สัญกรณ์ปกครองชวเลขการทำงานอย่างถูกต้องกับ difftool การคอมปกติ แต่ต่างจะกลับสำหรับการกระทำผสาน ทำไมเป็นเช่นนั้น
hIpPy

56

หากคุณรู้ว่าไกลแค่ไหนคุณสามารถลองทำสิ่งต่อไปนี้:

# Current branch vs. parent
git diff HEAD^ HEAD

# Current branch, diff between commits 2 and 3 times back
git diff HEAD~3 HEAD~2

ความมุ่งมั่นก่อนหน้านี้ทำงานบางอย่างเช่นนี้:

# Parent of HEAD
git show HEAD^1

# Grandparent
git show HEAD^2

มีหลายวิธีที่คุณสามารถระบุการผูกพัน:

# Great grandparent
git show HEAD~3

ดูหน้านี้สำหรับรายละเอียด


2
HEAD ^ 2 ไม่ใช่ปู่ย่าตายายถ้า HEAD ^ 1 เป็นพ่อแล้ว HEAD ^ 2 คือแม่ ใช้ HEAD ~ 2 เพื่อพ่อของพ่อ
Binarian

11

@mipadi ชี้ให้เห็นว่าคุณสามารถใช้งานgit show $COMMITได้ แต่สิ่งนี้ยังแสดงส่วนหัวและข้อความยืนยัน หากคุณต้องการความต่างตรงให้ใช้git show --pretty=format:%b $COMMITถ้าคุณต้องการความแตกต่างตรงการใช้งาน

เห็นได้ชัดว่านี่ไม่ใช่มือสั้น ๆ ดังนั้นฉันจึงใช้นามแฝงนี้เป็น. gitconfig

    [alias]
      sd = show --pretty=format:%b

ซึ่งจะช่วยให้ฉันไปใช้git sd $COMMITเพื่อแสดงให้เห็นความแตกต่าง


1
นามแฝงนี้อาจรวมถึง --color ซึ่งทำให้อ่านง่ายขึ้น: sd = show --color --pretty = รูปแบบ:% b
RichVel

@RichVel แน่นอน! จุดที่ดีมาก หากคุณเปิดใช้งานสีเป็นค่าเริ่มต้นในคอมไพล์คุณไม่จำเป็นต้องใช้สวิตช์นี้ นั่นคือสิ่งที่ฉันทำตามปกติ
Øystein Steimler

5

ตัวอย่างที่กล่าวถึงจำนวนมาก (เช่นgit diff 15dc8^!หรือgit diff 15dc8^..15dc8) ไม่ทำงานหากคุณใช้ zsh และมีextendedglobชุดตัวเลือก คุณสามารถแก้ไขได้ด้วยหนึ่งในสามวิธีต่อไปนี้:

  1. unsetopt extendedglob (และ / หรือลบออกจาก. zshrc)

  2. setopt NO_NOMATCH (และ / หรือกำหนดเป็น. zshrc)

  3. หลบคาเร็ตและปังทุกครั้งด้วยแบ็กสแลชเช่น git diff 15dc8\^\!



2

ทางออกของพอลด้านบนทำในสิ่งที่ฉันหวังไว้

$ git diff HEAD^1

นอกจากนี้ยังมีประโยชน์ในการเพิ่มชื่อแทนเช่น hobs ที่กล่าวถึงหากคุณใส่สิ่งต่อไปนี้ในส่วน [alias] ของไฟล์ ~ / .gitconfig ของคุณคุณสามารถใช้ทางลัดเพื่อดูความแตกต่างระหว่างส่วนหัวและก่อนหน้า

[alias]
    diff-last = diff HEAD^1

จากนั้นใช้$ git diff-lastจะได้ผลลัพธ์ โปรดทราบว่าสิ่งนี้จะรวมถึงการเปลี่ยนแปลงใด ๆ ที่คุณยังไม่ได้กระทำรวมถึงความแตกต่างระหว่างการกระทำ หากคุณต้องการเพิกเฉยต่อการเปลี่ยนแปลงที่คุณยังไม่ได้ทำคุณสามารถใช้ diff เพื่อเปรียบเทียบ HEAD กับพาเรนต์โดยตรง:

$ git diff HEAD^1 HEAD

0

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

alias gitdiff-1="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 2|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"
alias gitdiff-2="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 3|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"
alias gitdiff-3="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 4|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git diff"

alias gitlog-1="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 2|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
alias gitlog-2="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 3|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
alias gitlog-3="git log --reverse|grep commit|cut -d ' ' -f2|tail -n 4|head -n 2|xargs echo|sed -e 's/\s/../'|xargs -n 1 git log --summary"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.