git: จะแตกไฟล์ที่เปลี่ยนแปลงไปเทียบกับเวอร์ชันก่อนหน้าได้อย่างไร?


117

เมื่อฉันเรียกใช้ "git pull" ฉันมักต้องการทราบว่ามีอะไรเปลี่ยนแปลงระหว่างไฟล์เวอร์ชันล่าสุดกับไฟล์ใหม่ สมมติว่าฉันอยากรู้ว่าคนอื่นมุ่งมั่นกับไฟล์ใด

เป็นอย่างไรบ้าง?

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


1
คุณอาจพบว่าเครื่องมือกราฟิก gitk เหมาะกับรสนิยมของคุณมากขึ้น
crazyscot

stackoverflow.com/questions/61002/…อาจคล้ายกับอันนี้
VonC

คำตอบ:


158

ดู - มีทุกชนิดของวิธีที่ยอดเยี่ยมในการระบุกระทำที่มีการระบุการแก้ไขในส่วนของman git-rev-parseรายละเอียดเพิ่มเติม ในกรณีนี้คุณอาจต้องการ:

git diff HEAD@{1}

@{1}หมายถึง "ตำแหน่งก่อนหน้าของโทษที่ผมเคยระบุ" เพื่อให้ประเมินสิ่งที่คุณได้ตรวจสอบออกมาก่อนหน้านี้ - เพียงแค่ก่อนที่จะดึง คุณสามารถแก้ไขได้HEADในตอนท้ายหากคุณมีการเปลี่ยนแปลงบางอย่างในโครงสร้างงานของคุณและคุณไม่ต้องการเห็นความแตกต่างสำหรับพวกเขา

ฉันไม่แน่ใจว่าคุณกำลังขออะไรกับ "รหัสการกระทำของไฟล์เวอร์ชันล่าสุดของฉัน" การกระทำ "ID" (แฮช SHA1) คือเลขฐานสิบหก 40 อักขระที่ด้านบนของทุกรายการในเอาต์พุต ของบันทึกคอมไพล์ เป็นแฮชสำหรับคอมมิตทั้งหมดไม่ใช่ไฟล์ที่กำหนด คุณไม่ต้องการอะไรอีกแล้ว - หากคุณต้องการแตกต่างเพียงไฟล์เดียวในการดึงให้ทำ

git diff HEAD@{1} filename

นี่เป็นเรื่องทั่วไป - หากคุณต้องการทราบสถานะของไฟล์ในคอมมิตที่กำหนดให้คุณระบุคอมมิตและไฟล์ไม่ใช่ ID / แฮชเฉพาะสำหรับไฟล์


โพสต์ก่อนหน้าที่เชื่อมโยงของ VonC กล่าวว่าโดยพื้นฐานแล้วสิ่งเดียวกันกับสิ่งนี้ แต่คำอธิบายแตกต่างกันเล็กน้อยดังนั้นฉันจะปล่อยไว้ตอนนี้ (ใช้@{1}เป็นชวเลขด้วยHEAD@{1})
Cascabel

จริง แต่ฉันก็ชอบคำอธิบายเช่นกัน +1
VonC

นี่คือสิ่งที่ฉันกำลังค้นหา ขอบคุณสำหรับคำอธิบาย
lucapette

+1 สำหรับสิ่งที่ฉันเป็น googling จะดีมากถ้าเลือกนี้เป็นคำตอบและได้รับคะแนนสูงสุด ... :)
longda

@longda หากคุณจัดเรียงตามคะแนนโหวต (ซึ่งฉันคิดว่าเป็นค่าเริ่มต้น) มันควรจะอยู่ด้านบนแล้ว
Cascabel

57

ฉันชอบใช้:

git diff HEAD^

หรือถ้าฉันต้องการแตกไฟล์เฉพาะ:

git diff HEAD^ -- /foo/bar/baz.txt

5
-1: HEAD^เป็นผู้ปกครองกระทำไม่ใช่การกระทำก่อนpull
CharlesB

1
ถ้าHEADเป็นคอมมิตการผสานเป็นคอมมิตHEAD^แรกของพาเรนต์ใช่มันสามารถเป็นคอมมิตก่อนหน้าpull. เพื่อให้ได้ผู้ปกครองอื่น ๆ (สำหรับการผสานสองทาง) HEAD^2การใช้งาน แต่แล้วคำตอบข้างต้นไม่ได้ตอบคำถามในตอนแรกดังนั้นปล่อยให้ -1 ;-)
Michael Wild

ขอขอบคุณสำหรับการชี้แจง. ไม่ได้อ่านคำถามอย่างละเอียดเนื่องจากฉันกำลัง googling สำหรับสิ่งอื่นและลิงก์นี้ก็ปรากฏขึ้นในหน้าผลลัพธ์ ฉันคิดว่าฉันจะเข้ามาเพราะฉันเป็นผู้ใช้ใหม่และไม่มีกรรมใด ๆ (ถ้านั่นคือสิ่งที่เรียกว่า SO) ความผิดของฉัน =)
cadizm

3
@MichaelWild มันอาจจะไม่ใช่สิ่งที่ผู้ถามถาม แต่มันคือสิ่งที่ฉันกำลังมองหาเมื่อฉันพบสิ่งนี้ มันมีประโยชน์สำหรับฉัน Upvoting
John Dvorak

อันนี้คือสิ่งที่ TortoiseGit "Diff กับเวอร์ชันก่อนหน้า" ทำ และเป็นสิ่งที่ฉันกำลังมองหา
Fabien Haddadi

15

หากคุณทำตรงgit pullคุณจะถูก "ส่งต่ออย่างรวดเร็ว" หรือรวมจำนวนคอมมิทที่ไม่รู้จักจากที่เก็บระยะไกล นี้เกิดขึ้นเป็นหนึ่งในการดำเนินการแม้ว่าดังนั้นสุดท้ายกระทำที่คุณอยู่ในทันทีก่อนที่จะดึงจะเป็นรายการสุดท้ายใน reflog HEAD@{1}และสามารถเข้าถึงได้เป็น ซึ่งหมายความว่าคุณสามารถทำได้:

git diff HEAD@{1}

อย่างไรก็ตามฉันขอแนะนำเป็นอย่างยิ่งว่าหากนี่เป็นสิ่งที่คุณพบว่าตัวเองทำมากคุณควรพิจารณาเพียงแค่ทำgit fetchและตรวจสอบสาขาที่ดึงมาก่อนที่จะรวมหรือ rebitting ด้วยตนเอง เช่นหากคุณเป็นผู้เชี่ยวชาญและกำลังจะดึงต้นกำเนิด / ต้นแบบ:

git fetch

git log HEAD..origin/master

 # looks good, lets merge

git merge origin/master

ใช้git logแทนที่git diffนี่ได้ดี (แม้ว่าไวยากรณ์จะไม่ต่อเนื่องกันเล็กน้อยระหว่าง ".. " สำหรับgit logและ "... " สำหรับgit diff;) +1 โปรดดูstackoverflow.com/questions/53569/…และstackoverflow.com/questions / 850607 / …
VonC

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