显示提交之间的差异


236

我在Ubuntu 10.04(Lucid Lynx)上使用Git 。

我对我的主人做了一些承诺。

但是,我想弄清楚这些提交之间的区别。它们都在我的主分支上。

例如:

commit dj374
made changes

commit y4746
made changes

commit k73ud
made changes

我想得到k73ud和dj374之间的区别。但是,当我执行以下操作时,看不到在中所做的更改k73ud

git diff k73ud..dj374 > master.patch

Answers:


275

尝试

git diff k73ud^..dj374

确保k73ud在结果差异中包含的所有更改。

git diff比较两个端点(而不是提交范围)。由于OP希望看到带来的变化k73ud,他/她需要的差异之间的第一父提交的k73udk73ud^(或k73ud^1k73ud~)。

这样,diff结果将包含 k73ud父项以来的更改(意味着包括k73ud其自身的更改),而不是 k73uddj374以来引入的更改。

您也可以尝试:

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
你确定吗?git的差异275e8922ab4e995f47a753b88b75c3027444a54c..a8d9d944c32e945cbb9f60b3f724ecc580da86ae作品,但git的差异275e8922ab4e995f47a753b88b75c3027444a54c ^ .. a8d9d944c32e945cbb9f60b3f724ecc580da86ae得到错误信息- “未知版本或路径不工作的树”
DEMAS

@demas:在我的机器上工作;)您也可以使用,git diff 275e8^ a8d9d9因为它与' ..' 相同。
VonC

4
@VonC在我的机器上,无需使用^
xi.lin 2014年

5
@VonC Ubuntu 14.04。唯一git diff k73ud..dj374可以的
xi.lin 2014年

1
@BradyDowling同意。而且,如果您想查看PR差异,则可以在命令行中使用新的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

要查看两个不同提交之间的区别(我们将它们称为ab),请使用

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 '18年

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.还制作了一个显示diff的补丁文件,可用于将更改应用于另一个分支

如果未正确显示差异,
则c1和c2可能被认为是错误的,
因此请将它们调整为a,例如c1至c0之前的提交,或调整为c2至c3之后的提交

gitk看提交的SHA,1日为8个字符足以将它们作为C0,C1,C2或C3。您还可以从Gitlab>存储库>提交等中查看提交ID。

希望能有所帮助。


0

假设您在底部(最旧)还有一个提交,那么这变得很容易:

commit dj374
made changes

commit y4746
made changes

commit k73ud
made changes

commit oldestCommit
made changes

现在,使用下面的内容将轻松实现服务器的目的。

git diff k73ud oldestCommit

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.