git diff重命名文件


105

我有一个文件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。有一个吗?


我想如果您进行了“ git mv a.txt测试”,将会是一样的吗?在IE中,您只是重命名了文件,而不是将其移动到子目录中。
马克斯·沃特曼

Answers:


107

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
可以说提交包含多个文件更改。如何缩小到单个文件的差异?
平川健(Ken Hirakawa)

3
@KenHirakawa使用-- <old-path> <new-path>...看我的答案。
Nolan Amy

就我而言,我想显示提交文件重命名的详细信息,但这只是向我显示文件已被删除并添加了文件...我运行git show -C [commit]并识别出文件已重命名,并向我显示了文件之间的差异。完善。
杰森

83

要比较特定文件的重命名,请使用-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>]-查找重命名[= <n>]

检测重命名。如果n指定,则为相似性索引的阈值(即,与文件大小相比增加/删除的数量)。例如,-M90%如果没有超过90%的文件更改,则意味着Git应该将删除/添加对视为重命名。如果没有%符号,则该数字将被读为小数,在小数点之前。即,-M5变为0.5,因此与相同-M50%。同样,-M05与相同-M5%。要将检测限制为完全重命名,请使用-M100%。默认相似度索引为50%。


...当然,当更改和重命名位于单独的提交中时(如原始示例一样),也可以使用:git diff HEAD^^ HEAD -M -- a.txt test/a.txt
Nolan Amy

1
仅当文件内容足够接近以使diff提出相似性索引时。使用这两个选项(-M和-C)在已重命名并已完全更改(包括缩进)的文件中,显示从/ dev / null到/ dev / null的差异,甚至在忽略时也不捕获空格。
DavidG 2013年

37

您也可以这样做:

git diff rev1:file1 rev2:file2

以您的示例为例

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

请注意显式./-此格式否则将假设路径相对于仓库的根目录。(如果您位于存储库的根目录中,则可以忽略它。)

这根本不依赖于重命名检测,因为用户明确说明了要比较的内容。(因此,它在其他一些情况下也很方便,例如在git-svn环境中比较不同svn分支之间的文件。)


1
哦,太好了!
Nolan Amy

对于通过合并带来其他文件更改的重命名,这是唯一对我有用的答案。谢谢!
Lane Rettig

1

如果您的重命名提交已暂存但尚未提交,则可以使用:

git diff --cached -M -- file.txt renamed_file.txt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.