git diff 重命名文件
Posted
技术标签:
【中文标题】git diff 重命名文件【英文标题】:git diff renamed file 【发布时间】:2011-12-07 05:38:12 【问题描述】:我有一个文件a.txt
。
cat a.txt
> hello
a.txt
的内容是“hello”。
我做出承诺。
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
的等价物。有吗?
【问题讨论】:
我想如果你做一个'git mv a.txt test'会是一样的吗? IE 你只是重命名了文件,而不是将它移动到子目录中。 【参考方案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
顺便说一句,如果您将差异限制为仅一条路径(就像您在 git diff HEAD^^ HEAD a.txt
中所做的那样,您将永远不会看到重命名或副本,因为您已经排除了除了单个路径和重命名或副本之外的所有内容- 根据定义 - 涉及两条路径。
【讨论】:
可以说提交包含多个文件更改。我如何将其缩小到单个文件的差异? @KenHirakawa 使用-- <old-path> <new-path>
... 看我的回答。
在我的例子中,我想显示文件被重命名的提交的详细信息,但它只是显示一个文件被删除并添加了一个文件......我跑了@987654329 @ 并且它识别出文件重命名并向我展示了文件之间的差异。完美。【参考方案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
来自the git diff docs:
-M[
] --find-renames[= ] 检测重命名。如果指定
n
,则它是相似度指数的阈值(即添加/删除的数量 与文件的大小相比)。例如,-M90%
表示 Git 应该 如果超过 90% 的文件,则将删除/添加对视为重命名 没有改变。如果没有%
符号,则该数字将被读取为 分数,前面有小数点。即,-M5
变为 0.5,并且 因此与-M50%
相同。同样,-M05
与-M5%
相同。到 将检测限制为精确重命名,使用-M100%
。默认相似度 指数为 50%。
【讨论】:
...当然,当更改和重命名像原始示例一样在单独的提交中时也有效:git diff HEAD^^ HEAD -M -- a.txt test/a.txt
只有当文件的内容足够接近 diff 才能得出相似度索引时。使用这两个选项(-M 和 -C)会显示 /dev/null 与 /dev/null 的差异,该文件已重命名并已完全更改(包括缩进),忽略时它甚至不会捕获它空格。【参考方案3】:
你也可以这样做:
git diff rev1:file1 rev2:file2
以你的为例,应该是
git diff HEAD^^:./a.txt HEAD:./test/a.txt
注意显式的./
——否则这种格式假定路径是相对于回购根目录的。 (如果你在 repo 的根目录中,你当然可以省略它。)
这根本不依赖于重命名检测,因为用户明确说明了要比较的内容。 (因此,它在其他一些情况下也派上用场,例如在 git-svn 环境中比较不同 svn 分支之间的文件。)
【讨论】:
哦,这很好! 对于通过合并引入的附加文件更改的重命名,这是唯一对我有用的答案。谢谢! @LaneRettig 说了什么。奇怪,因为git diff dev
正确显示了有限的更改,但所有重命名检测建议都失败了,并将整个文件显示为新文件。所以这个答案有效,只是意味着你必须手动考虑重命名。【参考方案4】:
如果您的重命名提交已暂存但尚未提交,您可以使用:
git diff --cached -M -- file.txt renamed_file.txt
【讨论】:
以上是关于git diff 重命名文件的主要内容,如果未能解决你的问题,请参考以下文章