Git diff переименованный файл
У меня есть файл 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
. Есть один?
Ответы
Ответ 1
Проблема с разницей между 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
, вы никогда не увидите переименование или копии, потому что вы исключили все отдельно от одного пути и переименовали или копировали - по определению - задействовать два пути.
Ответ 2
Чтобы изменить переименование определенного файла, используйте -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-переименовывает [= < п > ]
Обнаружение переименований. Если указано n
, это пороговое значение для индекса подобия (то есть количество сложения/удаления по сравнению с размером файла). Например, -M90%
означает git should рассмотрите пару delete/add как переименование, если более 90% файла не изменилось. Без знака %
число должно быть считано как с точностью до десятичной точки. I.e., -M5
становится 0,5, и таким образом, совпадает с -M50%
. Аналогично, -M05
совпадает с -M5%
. к ограничить обнаружение для точных переименований, используйте -M100%
. По умолчанию сходство индекс равен 50%.
Ответ 3
Вы также можете сделать:
git diff rev1:file1 rev2:file2
который для вашего примера будет
git diff HEAD^^:./a.txt HEAD:./test/a.txt
Обратите внимание на явный ./
- этот формат в противном случае предполагает, что пути будут относиться к корню репо. (Если вы находитесь в корне репо, вы можете, конечно, опустить это.)
Это не зависит от обнаружения переименования вообще, так как пользователь явно указывает, что сравнивать. (Поэтому он также пригодится в некоторых других обстоятельствах, таких как сравнение файлов между различными ветвями svn в среде git -svn.)