如何在两个提交之间查看更改,而这两个提交之间没有其他提交?

818

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


19
"git diff" 始终显示两个提交(或提交和工作目录等)之间的差异。 - Jakub Narębski
41
@JakubNarębski问如何查看一个命令引入的更改与另一个提交引入的更改之间的差异,换句话说,即差异的差异或interdiff。 - psusi
1
如果您在diff命令中添加--dirstat=files参数,您将获得一个非常漂亮的截图,显示确切的项目和文件更改以及更改百分比。就像这样:git diff [commit-number] [commit-number] --dirstat=files - Óscar Ibáñez Fernández
1
如果您能添加示例git历史ASCII艺术并解释要从该图中区分/排除哪些提交,那么这个问题会更清晰明了。 - Thomas Guyot-Sionnest
@simpleuser 我指的是一般情况下的 "git diff" 命令,而不是没有任何参数的 git diff;无论如何,重要的是 "git diff" 始终涉及两个端点,并且始终跳过中间的提交。 - Jakub Narębski
显示剩余3条评论
15个回答

2

我在~/.bashrc文件中为git diff设置了alias

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

2

$git log

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

$git diff commit-2 commit-1

显示commit-2和commit-1之间的所有更改(仅commit-1的补丁,等同于git diff HEAD~1 HEAD

类似地, $git diff commit-4 commit-1

显示commit-4和commit-1之间的所有更改(commit-1、commit-2和commit-3的补丁合并在一起。等同于git diff HEAD~3 HEAD

$git diff commit-1 commit-2

通过更改提交ID的顺序,可以获得撤消补丁。("$git diff commit-1 commit-2 > revert_patch_of_commit-1.diff")


1
我编写了一个脚本,用于显示两个提交之间的差异,在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)

1

我在~/.zshrc文件中为git diff设置的alias

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

感谢 @Jinmiao Luo。

git diff HEAD~2 HEAD

显示最近第二个提交和当前提交之间的完整更改。

HEAD 非常方便。


-5

让我介绍一种易于使用的GUI /白痴证明方法,您可以在这些情况下采取。

  1. 克隆另一个副本到新文件夹,例如myRepo_temp
  2. 检出您想要与原始repo(myRepo_original)中的提交进行比较的提交/分支。
  3. 现在,您可以使用差异工具(如Beyond Compare等)来比较这两个文件夹(myRepo_tempmyRepo_original

例如,如果您想部分地撤消某些更改,则此方法非常有用,因为您可以从一个文件夹复制内容到另一个文件夹。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接