如何让git diff只显示两次提交之间的差异,而不包括中间的其他提交?


你可以简单地将2个提交传递给git diff,就像这样:

-> git diff 0da94be  59ff30c > my.patch
-> git apply my.patch

假设您想查看提交012345和abcdef之间的差异。以下内容可以达到你的目的:

$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached

只要求两次提交之间的差异而不包括中间的提交是没有意义的。提交只是存储库内容的快照;询问两者之间的区别必然包括它们。那么问题来了,你到底在寻找什么?

正如William所建议的,择优选择可以让您在另一个提交之上重新基于单个提交的增量。那就是:

$ git checkout 012345
$ git cherry-pick -n abcdef
$ git diff --cached

这将接受提交'abcdef',并将其与它的直接祖先进行比较,然后将该差值应用于'012345'。然后显示这个新的差异-唯一的变化是上下文来自'012345'而不是'abcdef的直接祖先'。当然,你可能会有冲突等等,所以在大多数情况下,这不是一个非常有用的过程。

如果你只对abcdef本身感兴趣,你可以这样做:

$ git log -u -1 abcdef

这将单独将abcdef与其直接祖先进行比较,这通常是您想要的结果。

当然

$ git diff 012345..abcdef

给出这两次提交之间的所有差异。

这将有助于更好地了解您试图实现的目标-正如我提到的,询问两次提交之间的差异而不考虑两者之间的差异实际上是没有意义的。


为了比较12345和abcdef作为补丁的两个git提交,可以使用diff命令作为

diff <(git show 123456) <(git show abcdef)

git diff <a-commit> <another-commit> path

例子:

git diff commit1 commit2 config/routes.rb

它显示了两次提交之间在该文件上的差异。


那么这个呢:

git diff abcdef 123456 | less

如果你想要在运行中比较许多不同的差异,将它管道到less是很方便的。


假设你有这个

A
|
B    A0
|    |
C    D
\   /
  |
 ...

你要确保A等于A0。

这样就可以了:

$ git diff B A > B-A.diff
$ git diff D A0 > D-A0.diff
$ diff B-A.diff D-A0.diff

我的别名设置在~/。git的Bashrc文件:

alias gdca='git diff --cached' # diff between your staged file and the last commit
alias gdcc='git diff HEAD{,^}' # diff between your latest two commits

我写了一个在两次提交之间显示差异的脚本,在Ubuntu上工作得很好。

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

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

TOOLS = ['bcompare', 'meld']

def getTool():
    for tool in TOOLS:
        try:
            out = subprocess.check_output(['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 = subprocess.check_output(['git', '-C', name, 'log', '--oneline', '--reverse']).split('\n')
        if first_index >= 0:
            commit1 = logs[first_index].split(' ')[0]
        if second_index >= 0:
            commit2 = logs[second_index].split(' ')[0]
    except ValueError:
        if first != '0':
            commit1 = first
        if second != '0':
            commit2 = second
    return commit1, commit2

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

def cleanup(commit1, commit2):
        subprocess.check_output(['rm', '-rf', '/tmp/'+(commit1 if commit1 != None else '0'), '/tmp/'+(commit2 if commit2 != None else '0')])

def checkoutCommit(name, commit):
    if commit != None:
        subprocess.check_output(['git', 'clone', name, '/tmp/'+commit])
        subprocess.check_output(['git', '-C', '/tmp/'+commit, 'checkout', commit])
    else:
        subprocess.check_output(['mkdir', '/tmp/0'])

def compare(tool, commit1, commit2):
        subprocess.check_output([tool, '/tmp/'+(commit1 if commit1 != None else '0'), '/tmp/'+(commit2 if commit2 != None else '0')])

if __name__=='__main__':
    tool = getTool()
    if tool == None:
        print "No GUI diff tools"
        sys.exit(0)
    if len(sys.argv) != 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 not validateCommitIds(name, commit1, commit2):
        sys.exit(0)

    cleanup(commit1, commit2)
    checkoutCommit(name, commit1)
    checkoutCommit(name, commit2)

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

从Git 2.19开始,你可以简单地使用:

Git range-diff rev1 -比较两个提交树,从它们的共同祖先开始

或 Git range-diff rev1~..rev1 rev2 ~ . . rev2 -比较2个提交所带来的变化


检查完整的更改:

  git diff <commit_Id_1> <commit_Id_2>

仅检查更改/添加/删除的文件:

  git diff <commit_Id_1> <commit_Id_2> --name-only

注意:对于检查中间没有提交的diff,你不需要输入提交id。


我的别名设置在~/。ZSHRC文件git diff:

alias gdf='git diff HEAD{'^',}' # diff between your recent tow commits

谢谢 @Jinmiao罗


git差别头~2头

在最近的第二次提交和当前之间完成更改。

HEAD方便


美元git日志

commit-1(new/latest/recent commit)
commit-2
commit-3
commit-4
*
*
commit-n(first commit)

$git diff commit-2

显示commit-2到commit-1之间的所有变化(仅仅是commit-1的补丁,相当于git diff HEAD~1 HEAD)

类似的 $git diff commit-4 commit-1

显示commit-4到commit-1之间的所有更改(commit-1的补丁, 一起提交2号和3号。相当于git差头~3头)

$git diff commit-1 commit-2

通过改变订单提交ID,可以获得恢复补丁。 ("$git diff commit-1 commit-2 > revert_patch_of_commit-1.diff")


让我来介绍一个简单的GUI/傻瓜证明方法,你可以在这些情况下采取。

克隆另一个副本到新文件夹,例如myRepo_temp 签出您想要与原始回购(myRepo_original)中的提交进行比较的提交/分支。 现在你可以使用不同的工具,(如超越比较等)与这两个文件夹(myRepo_temp和myRepo_original)

这是有用的,例如,如果你想部分逆转一些更改,因为你可以复制东西从一个文件夹到另一个文件夹。


直接在GitHub上查看差异;您可以- https://github.com/<username>/<reponame>/compare/<commit1>..<commit2> .

commit1和commit2可以是分支名或commit哈希值

为例:

比较gs/add-explicit-paths-to-js-files分支和gs/add-history-helper - https://github.com/twbs/bootstrap/compare/gs/add-explicit-paths-to-js-files..gs/add-history-helper 比较commit 75e09b1c0f5ae5f51078c7a25fe36d892c5cfcfe和585146a6a7aa70faf25442d7d28636ce57e29588 - https://github.com/twbs/bootstrap/compare/75e09b1c0f5ae5f51078c7a25fe36d892c5cfcfe..585146a6a7aa70faf25442d7d28636ce57e29588

在比较提交中阅读更多信息