How to see the changes between two commits without commits in-between?

大兔子大兔子 提交于 2019-12-17 06:19:28

问题


How do you make git diff only show the difference between two commits, excluding the other commits in-between?


回答1:


you can simply pass the 2 commits to git diff like :

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



回答2:


Asking for the difference /between/ two commits without including the commits in-between makes little sense. Commits are just snapshots of the contents of the repository; asking for the difference between two necessarily includes them. So the question then is, what are you really looking for?

As William suggested, cherry-picking can give you the delta of a single commit rebased on top of another. That is:

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

This takes commit 'abcdef', compares it to its immediate ancestor, then applies that difference on top of '012345'. This new difference is then shown - the only change is the context comes from '012345' rather than 'abcdef's immediate ancestor. Of course, you may get conflicts and etc, so it's not a very useful process in most cases.

If you're just interested in abcdef itself, you can do:

$ git log -u -1 abcdef

This compares abcdef to its immediate ancestor, alone, and is usually what you want.

And of course

$ git diff 012345..abcdef

gives you all differences between those two commits.

It would help to get a better idea of what you're trying to achieve - as I mentioned, asking for the difference between two commits without what's in between doesn't actually make sense.




回答3:


To compare two git commits 12345 and abcdef as patches one can use the diff command as

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



回答4:


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

Example:

git diff commit1 commit2 config/routes.rb

It shows the difference on that file between those commits.




回答5:


Let's say you have this

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

And you want to make sure that A is the same as A0.

This will do the trick:

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



回答6:


For checking complete changes:

  git diff <commit_Id_1> <commit_Id_2>

For checking only the changed/added/deleted files:

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

NOTE: For checking diff without commit in between, you don't need to put the commit ids.




回答7:


Suppose you want to see the difference between commits 012345 and abcdef. The following should do what you want:

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



回答8:


What about this:

git diff abcdef 123456 | less

It's handy to just pipe it to less if you want to compare many different diffs on the fly.




回答9:


My alias settings in ~/.bashrc file for git diff:

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

English is not my native language, please excuse typing errors




回答10:


Since Git 2.19, you can simply use:

git range-diff rev1...rev2 - compare two commit trees, starting by their common ancestor

or git range-diff rev1~..rev1 rev2~..rev2 - compare of changes introduced by 2 given commits




回答11:


I wrote a script which displays diff between two commits, works well on 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)



回答12:


My alias settings in ~/.zshrc file for git diff:

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

Thanks @Jinmiao Luo



来源:https://stackoverflow.com/questions/1191282/how-to-see-the-changes-between-two-commits-without-commits-in-between

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!