แสดงความแตกต่างระหว่างการกระทำ


236

ฉันใช้ Git บนUbuntu 10.04 (Lucid Lynx)

ฉันได้ให้คำมั่นสัญญากับนายของฉันแล้ว

อย่างไรก็ตามฉันต้องการได้รับความแตกต่างระหว่างการกระทำเหล่านี้ พวกเขาทั้งหมดอยู่ในสาขาหลักของฉัน

ตัวอย่างเช่น:

commit dj374
made changes

commit y4746
made changes

commit k73ud
made changes

ฉันต้องการรับความแตกต่างระหว่าง k73ud และ dj374 k73udแต่เมื่อฉันได้ดังต่อไปนี้ฉันไม่สามารถเห็นการเปลี่ยนแปลงที่ผมทำใน

git diff k73ud..dj374 > master.patch

คำตอบ:


275

ลอง

git diff k73ud^..dj374

เพื่อให้แน่ใจว่าจะรวมการเปลี่ยนแปลงทั้งหมดk73udในส่วนต่างที่เกิดขึ้น

git diffเปรียบเทียบสองจุดปลาย ( แทนที่จะเป็นช่วงกระทำ ) เนื่องจาก OP ต้องการเห็นการเปลี่ยนแปลงที่นำเสนอโดยk73udเขา / เธอต้องการความแตกต่างระหว่างการคอมพาเรนต์แรกของk73ud:k73ud^ (หรือk73ud^1หรือk73ud~ )

ด้วยวิธีนี้diffผลลัพธ์จะรวมการเปลี่ยนแปลงตั้งแต่ k73udผู้ปกครอง (ความหมายรวมถึงการเปลี่ยนแปลงจากk73udตัวเอง) แทนการเปลี่ยนแปลงที่แนะนำตั้งแต่ k73ud (จนถึงdj374)

นอกจากนี้คุณสามารถลอง:

git diff oldCommit..newCommit
git diff k73ud..dj374 

และ (1 ช่องว่างไม่เกิน):

git diff oldCommit newCommit
git diff k73ud dj374

และหากคุณต้องการชื่อไฟล์เท่านั้น (เช่นคัดลอกไฟล์แก้ไขด่วนด้วยตนเอง):

git diff k73ud dj374 --name-only

และคุณสามารถรับการเปลี่ยนแปลงที่นำไปใช้กับสาขาอื่น:

git diff k73ud dj374 > my.patch
git apply my.patch

5
คุณแน่ใจไหม? คอมไพล์ diff 275e8922ab4e995f47a753b88b75c3027444a54c..a8d9d944c32e945cbb9f60b3f724ecc580da86ae ประพฤติ แต่ 275e8922ab4e995f47a753b88b75c3027444a54c diff คอมไพล์ ^ .. a8d9d944c32e945cbb9f60b3f724ecc580da86ae ข้อความรับข้อผิดพลาด - "การแก้ไขที่ไม่รู้จักหรือเส้นทางที่ไม่ได้อยู่ในต้นไม้ทำงาน"
Demas

@demas: ทำงานบนเครื่องของฉัน;) คุณสามารถใช้งานได้git diff 275e8^ a8d9d9เพราะมันเหมือนกันแล้ว ' ..'
VonC

4
@VonC ในเครื่องของฉันไม่จำเป็นต้องใช้ ^
xi.lin

5
@VonC Ubuntu 14.04 git diff k73ud..dj374ตกลงเท่านั้น
xi.lin

1
@BradyDowling เห็นด้วย และถ้าคุณต้องการเห็น PR diff คุณสามารถทำได้ในบรรทัดคำสั่งด้วยghCLI ใหม่: stackoverflow.com/a/62031065/6309
VonC

126

หากต้องการดูความแตกต่างระหว่าง:

สำเนาการทำงานและพื้นที่การแสดงของคุณ:

% git diff

การจัดเตรียมพื้นที่และการคอมมิชชันล่าสุด:

% git diff --staged

สำเนาการทำงานของคุณและกระทำ 4ac0a6733:

% git diff 4ac0a6733

คอมมิท 4ac0a6733 และคอมมิทล่าสุด:

% git diff 4ac0a6733 HEAD

กระทำ 4ac0a6733 และส่ง 826793951

% git diff 4ac0a6733 826793951

สำหรับคำอธิบายเพิ่มเติมโปรดดูเอกสารอย่างเป็นทางการ


7
นอกจากนี้หากคุณต้องการเห็นความแตกต่างของไฟล์เดียวในคอมมิทเหล่านั้นgit diff {x} {y} -- filenameที่ไหน{x}และ{y}เป็นตัวอย่างใด ๆ ดูเพิ่มเติมgit log -pเนื่องจากมีบางส่วนทับซ้อนกัน
ไมเคิล

54

หากคุณต้องการดูการเปลี่ยนแปลงที่เกิดขึ้นในแต่ละการกระทำให้ลอง "git log -p"


13
  1. gitk --all
  2. เลือกการส่งครั้งแรก
  3. คลิกขวาที่อื่น ๆ แล้วเลือกที่แตกต่าง→นี้

ฉันเริ่มที่จะเชื่อใจ gitk น้อยลงเพราะมันแสดงให้เห็นถึงผู้แต่งที่แตกต่างจากผู้แต่งมากกว่าคนที่เกิดขึ้นจริง
Ciasto piekarz

10

ฉันใช้gitkเพื่อดูความแตกต่าง:

gitk k73ud..dj374

มันมีโหมด GUI เพื่อให้การตรวจสอบง่ายขึ้น


7

เมื่อต้องการดูความแตกต่างระหว่างการคอมมิทที่ต่างกัน (ลองเรียกมันaและb) ใช้

git diff a..b
  • โปรดทราบว่าความแตกต่างระหว่างaและbอยู่ตรงข้ามจากและba

หากต้องการดูความแตกต่างระหว่างการคอมมิตครั้งล่าสุดกับการเปลี่ยนแปลงที่ยังไม่ได้ทำให้ใช้

git diff

หากคุณต้องการกลับมาสู่ความแตกต่างในภายหลังคุณสามารถบันทึกเป็นไฟล์

git diff a..b > ../project.diff

5

ง่ายที่สุดสำหรับการตรวจสอบการเปลี่ยนแปลงใน 2 คอมมิทล่าสุดหลังจากดึง:

git diff HEAD~2 

3

ฉันเขียนสคริปต์ที่แสดงความแตกต่างระหว่างสองคอมมิทใช้งานได้ดีบน Ubuntu

https://gist.github.com/jacobabrahamb4/a60624d6274ece7a0bd2d141b53407bc

#!/usr/bin/env python
import sys, subprocess, os

TOOLS = ['bcompare', 'meld']

def execute(command):
    return subprocess.check_output(command)

def getTool():
    for tool in TOOLS:
        try:
            out = execute(['which', tool]).strip()
            if tool in out:
                return tool
        except subprocess.CalledProcessError:
            pass
    return None

def printUsageAndExit():
    print 'Usage: python bdiff.py <project> <commit_one> <commit_two>'
    print 'Example: python bdiff.py <project> 0 1'
    print 'Example: python bdiff.py <project> fhejk7fe d78ewg9we'
    print 'Example: python bdiff.py <project> 0 d78ewg9we'
    sys.exit(0)

def getCommitIds(name, first, second):
    commit1 = None
    commit2 = None
    try:
        first_index = int(first) - 1
        second_index = int(second) - 1
        if int(first) < 0 or int(second) < 0:
            print "Cannot handle negative values: "
            sys.exit(0)
        logs = execute(['git', '-C', name, 'log', '--oneline', '--reverse']).splitlines()
        if first_index >= 0:
            commit1 = logs[first_index].split(' ')[0]
        if second_index >= 0:
            commit2 = logs[second_index].split(' ')[0]
    except ValueError:
        if first is not '0':
            commit1 = first
        if second is not '0':
            commit2 = second
    return commit1, commit2

def validateCommitIds(name, commit1, commit2):
    if not commit1 and not commit2:
        print "Nothing to do, exit!"
        return False
    try:
        if commit1:
            execute(['git', '-C', name, 'cat-file', '-t', commit1])
        if commit2:
            execute(['git', '-C', name, 'cat-file', '-t', commit2])
    except subprocess.CalledProcessError:
        return False
    return True

def cleanup(commit1, commit2):
        execute(['rm', '-rf', '/tmp/'+(commit1 if commit1 else '0'), '/tmp/'+(commit2 if commit2 else '0')])

def checkoutCommit(name, commit):
    if commit:
        execute(['git', 'clone', name, '/tmp/'+commit])
        execute(['git', '-C', '/tmp/'+commit, 'checkout', commit])
    else:
        execute(['mkdir', '/tmp/0'])

def compare(tool, commit1, commit2):
        execute([tool, '/tmp/'+(commit1 if commit1 else '0'), '/tmp/'+(commit2 if commit2 else '0')])

if __name__=='__main__':
    tool = getTool()
    if not tool:
        print "No GUI diff tools, install bcompare or meld"
        sys.exit(0)
    if len(sys.argv) is not 4:
        printUsageAndExit()

    name, first, second = None, 0, 0
    try:
        name, first, second = sys.argv[1], sys.argv[2], sys.argv[3]
    except IndexError:
        printUsageAndExit()

    commit1, commit2 = getCommitIds(name, first, second)

    if validateCommitIds(name, commit1, commit2) is False:
        sys.exit(0)

    cleanup(commit1, commit2)

    try:
        checkoutCommit(name, commit1)
        checkoutCommit(name, commit2)
        compare(tool, commit1, commit2)
    except KeyboardInterrupt:
        pass
    finally:
        cleanup(commit1, commit2)
    sys.exit(0)

1
สคริปต์ที่น่าสนใจ +1
VonC

2

คำตอบที่ได้รับการยอมรับเป็นสิ่งที่ดี

เพียงวางไว้ที่นี่อีกครั้งเพื่อให้เข้าใจง่ายและลองในอนาคต

git diff c1...c2 > mypatch_1.patch  
git diff c1..c2  > mypatch_2.patch  
git diff c1^..c2 > mypatch_3.patch  

ฉันได้ต่างกันสำหรับคำสั่งทั้งหมดข้างต้น

ข้างต้นช่วยใน
1. เห็นความแตกต่างระหว่างการกระทำ c1 และการกระทำอื่น c2
2. ยังทำไฟล์ปะที่แสดงความแตกต่างและสามารถใช้เพื่อนำการเปลี่ยนแปลงไปใช้กับสาขาอื่น

หากมันไม่แสดงความแตกต่างอย่างถูกต้อง
c1 & c2 อาจผิดได้
ดังนั้นปรับเป็น a ก่อนคอมมิทเช่น c1 ถึง c0 หรือหนึ่งหลังจาก c2 ถึง c3

ใช้gitkเพื่อดูการกระทำของ SHA, อักขระ 8 ตัวแรกนั้นเพียงพอที่จะใช้เป็น c0, c1, c2 หรือ c3 คุณยังสามารถดูรหัสการกระทำจาก Gitlab> ที่เก็บ> การกระทำ ฯลฯ

หวังว่าจะช่วย


0

สมมติว่าคุณมีความมุ่งมั่นอีกครั้งที่ด้านล่าง (เก่าที่สุด) จากนั้นสิ่งนี้จะค่อนข้างง่าย:

commit dj374
made changes

commit y4746
made changes

commit k73ud
made changes

commit oldestCommit
made changes

ตอนนี้การใช้ด้านล่างจะทำให้เซิร์ฟเวอร์เป็นไปอย่างง่ายดาย

git diff k73ud oldestCommit

-2

ใช้คำสั่งนี้สำหรับความแตกต่างระหว่างการกระทำและ unstaged:

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