同じブランチ上の2つの異なるコミット間で同じファイルを比較するにはどうすればよいですか?


1144

Gitで、同じブランチ(たとえばマスター)上の2つの異なるコミット(隣接していない)の間で同じファイルをどのように比較できますか?

Visual SourceSafe(VSS)やTeam Foundation Server(TFS)のような比較機能を探しています。 Gitでそれは可能ですか?

回答:


1476

git-diffマンページから:

git diff [--options] <commit> <commit> [--] [<path>...]

たとえば、「main.c」というファイルの現在のコミットと2つのコミットの違いを確認するには、次の3つの同等のコマンドを使用します。

$ git diff HEAD^^ HEAD main.c
$ git diff HEAD^^..HEAD -- main.c
$ git diff HEAD~2 HEAD -- main.c

43
これ..は機能しますが、実際には必要ありません(かなり古いバージョンを除いて)。2つのコミットが非常に離れている場合は、git logまたはgitkを使用して、使用するSHA1を見つけることもできます。gitkまた、コンテキストメニューに「diff selected-> this」と「diff this-> selected」があります。
カスカベル

17
2つのコミットの間にファイル名が変更されても、これは機能しますか?
reubenjohn 2014

26
それで、「-」の目的は何
ですか

29
@ user64141 --は、という名前のファイルがある場合などに便利です-p。スクリプトで使用すると効果的ですが、実際に必要になるのはまれな場合だけです。
Palec、2014

13
注:リポジトリのルートからの相対パスを使用する必要があります。現在の作業ディレクトリからの相対パスは機能しません。
Kevin Wheeler 2015年

281

次のように、2つの異なるリビジョンの2つの異なるファイルを比較することもできます。

git diff <revision_1>:<file_1> <revision_2>:<file_2>


25
それは場合のように見えることに注意<file_1>して<file_2>、現在のディレクトリではなく、トップレベルのgitの管理ディレクトリにあり、1が先頭に追加する必要があり./ます。UNIXの場合<revision_1>:./filename_1
アンドレホルズナー

7
<リビジョン>:省略できるので、まだコミットされていないファイルと比較できます。
Yaroslav Nikitenko

2
Windowsでは、ファイルパスに「\」ではなく「/」を使用する必要があることに注意してください。
np8 2018年

88

「difftool」を設定している場合は、使用できます

git difftool revision_1:file_1 revision_2:file_2

例:同じブランチ上でファイルを最後のコミットから以前のコミットに比較:プロジェクトのルートフォルダーにいる場合

$git difftool HEAD:src/main/java/com.xyz.test/MyApp.java HEAD^:src/main/java/com.xyz.test/MyApp.java

〜/ .gitconfigまたはproject / .git / configファイルに次のエントリがあるはずです。p4mergeをインストールします[これは私の好みの差分およびマージツールです]

[merge]
    tool = p4merge
    keepBackup = false
[diff]
    tool = p4merge
    keepBackup = false
[difftool "p4merge"]
    path = C:/Program Files (x86)/Perforce/p4merge.exe
[mergetool]
    keepBackup = false
[difftool]
    keepBackup = false
[mergetool "p4merge"]
    path = C:/Program Files (x86)/Perforce/p4merge.exe
    cmd = p4merge.exe \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"

50

チェックして$ git log、2つの異なるコミットのSHA-1 IDをコピーし、git diffそれらのIDを使用してコマンドを実行します。例えば:

$ git diff (sha-id-one) (sha-id-two)

18
特定のファイルのdiffが必要な場合は、コマンドの最後にそのファイルへのパスを追加します。
hBrent 2015

また、2つのコミットが異なるブランチにまたがっている場合は、「git pull」を実行して完全なツリー情報をダウンロードします。そうしないと、「致命的:不正なオブジェクト」エラーが発生します。
user238607

4
git diff (sha-id-one) (sha-id-two) -- filename.ext ファイル名がない場合、これらの2つのコミットのすべてのファイルの差分がリストされます。
SherylHohman

40

コミットごとに2つのコミット間のファイルへのすべての変更を確認する場合は、次のようにすることもできます。

git log -u $start_commit..$end_commit -- path/to/file


「$ start_commit」および「$ end_commit」とは何ですか?それらは文字通りですか、そうでない場合、例を提供できますか?
Peter Mortensen、

これらは、最初と最後のリビジョンを含むシェル変数であり、代わりにsha1リテラルまたは参照にすることができます
cxreg

21

これは、Gitログコマンドで見つかった特定のファイルのGit diffコマンドを出力するPerlスクリプトです。

例えば

git log pom.xml | perl gldiff.pl 3 pom.xml

収量:

git diff 5cc287:pom.xml e8e420:pom.xml
git diff 3aa914:pom.xml 7476e1:pom.xml
git diff 422bfd:pom.xml f92ad8:pom.xml

次に、シェルウィンドウセッションでカットアンドペーストするか、パイプでに転送し/bin/shます。

ノート:

  1. 数値(この場合は3)は、印刷する行数を指定します
  2. ファイル(この場合はpom.xml)は両方で一致する必要があります(シェル関数でラップして両方に同じファイルを提供することもできます)、またはそれをシェルスクリプトとしてバイナリディレクトリに配置する必要があります

コード:

# gldiff.pl
use strict;

my $max  = shift;
my $file = shift;

die "not a number" unless $max =~ m/\d+/;
die "not a file"   unless -f $file;

my $count;
my @lines;

while (<>) {
    chomp;
    next unless s/^commit\s+(.*)//;
    my $commit = $1;
    push @lines, sprintf "%s:%s", substr($commit,0,6),$file;
    if (@lines == 2) {
        printf "git diff %s %s\n", @lines;
        @lines = ();
    }
    last if ++$count >= $max *2;
}

14

@mipadiで指定されたメソッドを使用して、複数のファイルでdiffを作成する場合:

たとえば、HEADとの差分を作成してmaster、すべての.coffeeファイルを見つけます。

git diff master..HEAD -- `find your_search_folder/ -name '*.coffee'`

これによりyour_search_folder/、すべての.coffeeファイルが再帰的に検索され、それらのファイルとそのmasterバージョンとの差分が作成されます。


13

複数のファイルまたはディレクトリがあり、非継続的なコミットを比較したい場合、これを行うことができます:

一時的なブランチを作成します(この例では「リビジョン」

git checkout -b revision

最初のコミットターゲットまで巻き戻し

git reset --hard <commit_target>

興味のあるコミットのチェリーピッキング

git cherry-pick <commit_interested> ...

差分を適用

git diff <commit-target>^

終わったら

git branch -D revision

2
この解決策をありがとう。私のユースケースではうまくいきました。私が更新する唯一のものは、あなたがそれを終えたとき、あなたがそれをオフにするまでブランチを削除できないということです。
Steven Dix 2013

9

Gitの素晴らしさを使用するもう1つの方法...

git difftool HEAD HEAD@{N} /PATH/FILE.ext

:私はbashのと連動し、この答えから別名定義されたdifftool-file = "!git difftool HEAD@{\"$2\"} HEAD \"$1\" #"
blueogive

2

Visual SourceSafeTeam Foundation Server(TFS)で取得できるようなWindowsでの単純な視覚的比較が必要な場合は、次のことを試してください。

  • エクスプローラーでファイルを右クリック
  • 「Git History」を選択します

注:Windows 10にアップグレードした後、Gitコンテキストメニューオプションが失われました。ただし、コマンドウィンドウで「gitk」または「gitk filename」を使用して同じことを実現できます。

「Git履歴」を呼び出すと、Git GUIツールが起動し、左上のペインにファイルの履歴が表示されます。比較するバージョンの1つを選択します。次に、2番目のバージョンを右クリックし、いずれかを選択します

これを比較->選択

または

選択した差分->これ

色分けされた違いが左下のペインに表示されます。


反対投票者への注意:これはシンプルなソリューションであり、実装が簡単で、OPの問題に対処します。これは、OPが明確に使用しているWindowsで動作します(質問のTFSおよびVSSへの参照を参照)。
リソース
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.