web-dev-qa-db-ja.com

git diffの名前が変更されたファイル

ファイルa.txtがあります。

cat a.txt
> hello

a.txtの内容は「hello」です。

コミットします。

git add a.txt
git commit -m "first commit"

次に、a.txttest dirに移動します。

mkdir test
mv a.txt test

次に、2回目のコミットを行います。

git add -A
git commit -m "second commit"

最後に、a.txtを編集して、代わりに「さようなら」と言います。

cat a.txt
> goodbye

最後にコミットします。

git add a.txt
git commit -m "final commit"

ここに私の質問があります:

最後のコミットと最初のコミットの間でa.txtの内容をどのように比較しますか?

私は試しました:git diff HEAD^^..HEAD -M a.txt、しかしそれはうまくいきませんでした。 git log --follow a.txtは名前の変更を適切に検出しますが、git diffに相当するものが見つかりません。あるの?

98
Ken Hirakawa

HEAD^^HEADの違いの問題は、両方のコミットにa.txtがあるため、これらの2つのコミット(diffの動作)を考慮するだけで、名前の変更はありません。 、コピーと変更があります。

コピーを検出するには、-Cを使用できます。

git diff -C HEAD^^ HEAD

結果:

index ce01362..dd7e1c6 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1 @@
-hello
+goodbye
diff --git a/a.txt b/test/a.txt
similarity index 100%
copy from a.txt
copy to test/a.txt

ちなみに、diffを1つのパスのみに制限する場合(git diff HEAD^^ HEAD a.txtで行うように、単一のパスと名前変更またはコピー以外のすべてを除外したため、名前変更またはコピーは表示されません-定義により-2つのパスが含まれます。

105
CB Bailey

特定のファイルの名前変更を比較するには、-M -- <old-path> <new-path>を使用します(-Cも機能します)。

そのため、最後のコミットでファイルの名前を変更および変更した場合、次のように変更を確認できます。

git diff HEAD^ HEAD -M -- a.txt test/a.txt

これにより、以下が生成されます。

diff --git a/a.txt b/test/a.txt
similarity index 55%
rename from a.txt
rename to test/a.txt
index 3f855b5..949dd15 100644
--- a/a.txt
+++ b/test/a.txt
@@ -1,3 +1,3 @@
 // a.txt

-hello
+goodbye

// a.txt行が追加され、gitが名前変更を検出できるようになりました)


gitが名前の変更を検出しない場合、-M[=n]で低い類似度のしきい値を指定できます。たとえば、1%:

git diff HEAD^ HEAD -M01 -- a.txt test/a.txt

git diff docs から:

-M [<n>] --find-renames [= <n>]

名前の変更を検出します。 nが指定されている場合、これは類似性インデックスのしきい値(つまり、ファイルのサイズと比較した追加/削除の量)です。たとえば、-M90%は、ファイルの90%以上が変更されていない場合、Gitが削除/追加ペアを名前変更と見なすべきであることを意味します。 %記号がない場合、数値は小数部として読み取られ、その前に小数点が付きます。つまり、-M5は0.5になるため、-M50%と同じになります。同様に、-M05-M5%と同じです。検出を正確な名前変更に制限するには、-M100%を使用します。デフォルトの類似性インデックスは50%です。

74
Nolan Amy

次のこともできます。

git diff rev1:file1 rev2:file2

あなたの例では、

git diff HEAD^^:./a.txt HEAD:./test/a.txt

明示的な./に注意してください-そうでない場合、この形式は、パスがレポのルートに相対的であると想定します。 (レポのルートにいる場合は、もちろん省略できます。)

これは、ユーザーが比較対象を正確に明示しているため、名前変更の検出にまったく依存しません。 (そのため、git-svn環境の異なるsvnブランチ間でファイルを比較するなど、他の状況でも役立ちます。)

29
benkc

名前変更コミットがステージングされているがまだコミットされていない場合は、次を使用できます。

git diff --cached -M -- file.txt renamed_file.txt
1
Mr-IDE