git diff переименовал файл - PullRequest
97 голосов
/ 13 октября 2011

У меня есть файл a.txt.

cat a.txt
> hello

Содержимое a.txt - "привет".

Я делаю коммит.

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

Затем я перемещаю a.txt в test реж.

mkdir test
mv a.txt test

Затем я делаю второй коммит.

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. Есть ли один?

Ответы [ 4 ]

104 голосов
/ 13 октября 2011

Проблема с разницей между HEAD^^ и HEAD заключается в том, что у вас есть a.txt в обоих коммитах, поэтому, просто учитывая эти два коммита (что и делает 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 только одним путем (как вы делаете в git diff HEAD^^ HEAD a.txt, вы никогда не увидите переименования или копии, потому что вы исключили все, кроме одного пути и переименований или копий - по определению - включает два пути.

73 голосов
/ 11 марта 2013

Чтобы различать переименование определенного файла, используйте -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 [] --find-renames [= ]

Обнаружение переименований.Если указано n, это пороговое значение индекса сходства (т. Е. Количество добавлений / удалений по сравнению с размером файла).Например, -M90% означает, что Git должен считать пару «удалить / добавить» переименованием, если более 90% файла не изменилось.Без знака % число читается в виде дроби с десятичной точкой перед ним.Т.е. -M5 становится равным 0,5 и, таким образом, совпадает с -M50%.Точно так же -M05 совпадает с -M5%.Чтобы ограничить обнаружение точными переименованиями, используйте -M100%.Индекс сходства по умолчанию составляет 50%.

27 голосов
/ 15 мая 2015

Вы также можете сделать:

git diff rev1:file1 rev2:file2

, который, для вашего примера, будет

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

Обратите внимание на явный ./ - этот формат предполагает, что пути должны быть относительно корня репо. (Если вы находитесь в корне репо, вы, конечно, можете это опустить.)

Это вообще не зависит от обнаружения переименования, поскольку пользователь явно указывает, что именно сравнивать. (Следовательно, это также полезно в некоторых других обстоятельствах, таких как сравнение файлов между различными ветками svn в среде git-svn.)

1 голос
/ 24 июня 2018

Если ваш коммит переименования находится в стадии постановки, но еще не зафиксирован, вы можете использовать:

git diff --cached -M -- file.txt renamed_file.txt
...