我有一个文件
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
的等效项。 有吗
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
顺便说一句,如果您将差异限制为只有一个路径(就像您在
git diff HEAD^^ HEAD a.txt
中所做的那样,您将永远不会看到重命名或副本,因为您已经排除了除单个路径和重命名或副本之外的所有内容 - 通过定义 - 涉及两条路径。
要对特定文件的重命名进行比较,请使用
-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 文档:
-M[] --查找重命名[=
检测重命名。如果指定了]
n
,则它是相似性指数的阈值(即添加/删除的数量 与文件大小相比)。例如,-M90%
表示 Git 应该 如果文件的 90% 以上,则将删除/添加对视为重命名 没有改变。如果没有%
符号,该数字将被解读为 分数,前面有小数点。即,-M5
变为 0.5,并且 因此与-M50%
相同。同样,-M05
与-M5%
相同。到 将检测限制为精确重命名,请使用-M100%
。默认相似度 指数为50%。
git diff rev1:file1 rev2:file2
git diff HEAD^^:./a.txt HEAD:./test/a.txt
./
——此格式否则假定路径相对于存储库的根。 (如果您位于存储库的根目录中,您当然可以省略它。)这根本不依赖于重命名检测,因为用户明确说明了要比较的内容。 (因此,在其他一些情况下它也派上用场,例如在 git-svn 环境中比较不同 svn 分支之间的文件。)
git diff --cached -M -- file.txt renamed_file.txt
Git 1.6 及以上版本可以使用更方便的“staged”标志:
git diff --staged -M -- path/to/file.txt path/to/renamed_file.txt
相同的命令也适用于 git difftool
,启动第三方视觉差异工具(您必须首先配置):
git difftool --tool=p4merge --staged -M -- file.txt renamed_file.txt