Hiển thị khác nhau giữa các cam kết


234

Tôi đang sử dụng Git trên Ubuntu 10.04 (Lucid Lynx).

Tôi đã thực hiện một số cam kết với chủ của tôi.

Tuy nhiên, tôi muốn có được sự khác biệt giữa các cam kết này. Tất cả chúng đều nằm trên nhánh chính của tôi.

Ví dụ:

commit dj374
made changes

commit y4746
made changes

commit k73ud
made changes

Tôi muốn có được sự khác biệt giữa k73ud và dj374. Tuy nhiên, khi tôi làm như sau tôi không thể thấy những thay đổi tôi đã thực hiện k73ud.

git diff k73ud..dj374 > master.patch

Câu trả lời:


273

Thử

git diff k73ud^..dj374

để đảm bảo bao gồm tất cả các thay đổi k73udtrong kết quả khác.

git diffso sánh hai điểm cuối ( thay vì phạm vi cam kết ). Vì OP muốn xem các thay đổi được giới thiệu bởi k73ud, anh ấy / cô ấy cần phải khác biệt giữa cam kết cha mẹ đầu tiên của k73ud:k73ud^ ( k73ud^1hoặck73ud~ ).

Bằng cách đó, diffkết quả sẽ bao gồm các thay đổi kể từ k73ud cha mẹ (có nghĩa là bao gồm các thay đổi từ k73udchính nó), thay vì các thay đổi được giới thiệu kể từ k73ud (tối đa dj374).

Ngoài ra, bạn có thể thử:

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

và (1 dấu cách, không nhiều hơn):

git diff oldCommit newCommit
git diff k73ud dj374

Và nếu bạn chỉ cần lấy tên tệp (ví dụ: sao chép hotfix thủ công):

git diff k73ud dj374 --name-only

Và bạn có thể nhận được các thay đổi được áp dụng cho một chi nhánh khác:

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

5
Bạn có chắc không? git diff 275e8922ab4e995f47a753b88b75c3027444a54c..a8d9d944c32e945cbb9f60b3f724ecc580da86ae công trình, nhưng git diff 275e8922ab4e995f47a753b88b75c3027444a54c ^ .. a8d9d944c32e945cbb9f60b3f724ecc580da86ae get thông báo lỗi - "sửa đổi chưa được biết hoặc đường dẫn không trong cây làm việc"
DEMAS

@demas: hoạt động trên máy của tôi;) bạn cũng có thể sử dụng git diff 275e8^ a8d9d9vì nó giống nhau rồi ' ..'.
VonC

4
@VonC Trong máy của tôi, không cần sử dụng ^
xi.lin

5
@VonC Ubuntu 14.04. Chỉ git diff k73ud..dj374là OK
xi.lin

1
@BradyDowling Đồng ý. Và nếu bạn muốn xem PR diff, bạn có thể thực hiện trong dòng lệnh với ghCLI mới : stackoverflow.com/a/62031065/6309
VonC

125

Để thấy sự khác biệt giữa:

Bản sao làm việc và khu vực tổ chức của bạn:

% git diff

Khu vực tổ chức và cam kết mới nhất:

% git diff --staged

Bản sao làm việc của bạn và cam kết 4ac0a6733:

% git diff 4ac0a6733

Cam kết 4ac0a6733 và cam kết mới nhất:

% git diff 4ac0a6733 HEAD

Cam kết 4ac0a6733 và cam kết 826793951

% git diff 4ac0a6733 826793951

Để được giải thích thêm xem tài liệu chính thức .


7
Ngoài ra, nếu bạn thực sự chỉ muốn xem một khác biệt của các tệp trong các cam kết đó, thì git diff {x} {y} -- filenameđâu {x}{y}là bất kỳ ví dụ nào được đưa ra. Xem thêm git log -p, vì có một số chồng chéo.
michael

54

Nếu bạn muốn xem các thay đổi được giới thiệu với mỗi cam kết, hãy thử "git log -p"


13
  1. gitk --all
  2. Chọn cam kết đầu tiên
  3. Nhấp chuột phải vào cái khác, sau đó chọn diff → cái này

Tôi bắt đầu tin tưởng gitk ít hơn một chút vì nó đang hiển thị một tác giả khác nhau so với thực tế.
Ciasto piekarz

10

Tôi sử dụng gitkđể thấy sự khác biệt:

gitk k73ud..dj374

Nó có chế độ GUI để việc xem xét dễ dàng hơn.


7

Để xem sự khác biệt giữa hai cam kết khác nhau (hãy gọi chúng ab), sử dụng

git diff a..b
  • Lưu ý rằng sự khác biệt giữa abngược lại với ba.

Để xem sự khác biệt giữa các cam kết cuối cùng của bạn và các thay đổi chưa được cam kết, hãy sử dụng

git diff

Nếu bạn muốn có thể quay lại sự khác biệt sau này, bạn có thể lưu nó trong một tệp.

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

5

Đơn giản nhất để kiểm tra các thay đổi trong 2 lần xác nhận cuối cùng sau khi kéo:

git diff HEAD~2 

3

Tôi đã viết một tập lệnh hiển thị khác nhau giữa hai lần xác nhận, hoạt động tốt trên 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
Kịch bản thú vị. +1
VonC

2

Chấp nhận câu trả lời là tốt.

Chỉ cần đặt lại ở đây, để dễ hiểu và thử trong tương lai

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

Tôi đã nhận được cùng một khác cho tất cả các lệnh trên.

Ở trên giúp trong
1. thấy sự khác biệt giữa cam kết c1 và cam kết khác c2
2. cũng tạo một tệp vá hiển thị khác và có thể được sử dụng để áp dụng các thay đổi cho chi nhánh khác

Nếu nó không hiển thị chính xác sự khác biệt
thì c1 & c2 có thể bị sai,
vì vậy hãy điều chỉnh chúng thành a trước khi cam kết như c1 thành c0 hoặc sau một như sau c2 thành c3

Sử dụng gitkđể xem các cam kết SHA, 8 ký tự đầu tiên là đủ để sử dụng chúng như c0, c1, c2 hoặc c3. Bạn cũng có thể thấy các id xác nhận từ Gitlab> Kho lưu trữ> Cam kết, v.v.

Mong rằng sẽ giúp.


0

Giả sử bạn có thêm một cam kết ở phía dưới (cũ nhất), thì điều này trở nên khá dễ dàng:

commit dj374
made changes

commit y4746
made changes

commit k73ud
made changes

commit oldestCommit
made changes

Bây giờ, sử dụng dưới đây sẽ dễ dàng máy chủ mục đích.

git diff k73ud oldestCommit

-2

Sử dụng lệnh này cho sự khác biệt giữa cam kết và không được tổ chức:

git difftool --dir-diff
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.