web-dev-qa-db-ja.com

コミットを途中で行わずに2つのコミット間の変更を確認する方法

どのようにgit diffに2つのコミット間の違いのみを表示させ、その間にある他のコミットを除くようにしますか?

564
user146069

2つのコミットを渡してgit diffを実行するだけです。

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

その間のコミットを含めずに/ between/2コミットの違いを尋ねることはほとんど意味がありません。コミットはリポジトリの内容の単なるスナップショットです。 2つの違いを尋ねることは必然的にそれらを含みます。それで問題はそれで、あなたは本当に何を探していますか?

ウィリアムが示唆したように、チェリーピッキングはあなたに別のものの上にリベースされた単一のコミットのデルタを与えることができます。あれは:

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

これはコミット 'abcdef'を取り、それを直近の先祖と比較してから その差 '012345'の上に適用します。この新しい違いがそれから示されます - 唯一の変化は文脈が 'abcdefの直接の先祖よりむしろ' 012345 'から来るということです。もちろん、衝突などが起こる可能性があるので、ほとんどの場合、それはあまり便利なプロセスではありません。

Abcdef自体に興味があるだけなら、次のようにします。

$ git log -u -1 abcdef

これはabcdefとその直系の祖先を単独で比較するもので、通常はあなたが望むものです。

そしてもちろん

$ git diff 012345..abcdef

これら2つのコミットの間のすべての違いがわかります。

何を達成しようとしているのかをよりよく理解するのに役立ちます - 私が述べたように、2つのコミットの間の違いを求めずにその間に何があるのか​​を実際には意味がありません。

126
bdonlan

2つのgitコミット12345とabcdefをパッチとして比較するには、diffコマンドを次のように使用します。

diff <(git show 123456) <(git show abcdef)
71
plexoos
git diff <a-commit> <another-commit> path

例:

git diff commit1 commit2 config/routes.rb

それはそれらのコミットの間のそのファイルの違いを示しています。

57
roadev

これがあるとしましょう

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

そしてAA0と同じであることを確認したいと思います。

これでうまくいくでしょう。

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

012345とabcdefのコミットの違いを調べたいとしましょう。以下はあなたが望むことをするはずです:

 $ gitチェックアウト012345 
 $ git cherry-pick -n abcdef 
 $ git diff --cached 
12
William Pursell

これはどうですか:

git diff abcdef 123456 | less

あなたがその場で多くの異なるdiffを比較したいならば、それを単にlessにパイプすることは便利です。

9
Flow Overstack

完全な変更をチェックするために:

  git diff <commit_Id_1> <commit_Id_2>

変更/追加/削除されたファイルのみをチェックする場合:

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

_ note _ :間でコミットせずにdiffをチェックするために、コミットIDを置く必要はありません。

5
bit_cracker007

~/.bashrcgit diffファイルの私のalias設定:

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

英語は私の母国語ではありません、入力ミスを許してください

2
Jinmiao Luo

Git 2.19以降、あなたは単に使うことができます:

git range-diff <rev1>...<rev2>

0
Tomáš Diviš

私は2つのコミット間の差分を表示し、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)
0
Jacob Abraham