git diff 重命名文件

发布于 2024-12-09 20:31:41 字数 797 浏览 0 评论 0原文

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

I have a file a.txt.

cat a.txt
> hello

The contents of a.txt is "hello".

I make a commit.

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

I then move a.txt into a test dir.

mkdir test
mv a.txt test

I then make my second commit.

git add -A
git commit -m "second commit"

Finally, I edit a.txt to say "goodbye" instead.

cat a.txt
> goodbye

I make my last commit.

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

Now here is my question:

How do I diff the contents of a.txt between my last commit and my first commit?

I've tried:
git diff HEAD^^..HEAD -M a.txt, but that didn't work. git log --follow a.txt properly detects the rename, but I can't find an equivalent for git diff. Is there one?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

翻了热茶 2024-12-16 20:31:41

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 您永远不会看到重命名或副本,因为您已经排除了除单个路径之外的所有内容,并且重命名或副本(根据定义)涉及两个路径。

The issue with the difference between HEAD^^ and HEAD is that you have an a.txt in both commits, so just considering those two commits (which is what diff does), there is no rename, there is a copy and a change.

To detect copies, you can use -C:

git diff -C HEAD^^ HEAD

Result:

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

Incidentally, if you restrict your diff to just one path (as you do in git diff HEAD^^ HEAD a.txt you aren't ever going to see the renames or copies because you've excluded the everything apart from a single path and renames or copies - by definition - involve two paths.

許願樹丅啲祈禱 2024-12-16 20:31:41

要区分特定文件的重命名,请使用 -M ---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[]
--find-renames[=]

检测重命名。如果指定了n,则它是相似性指数的阈值(即添加/删除的数量)
与文件大小相比)。例如,-M90% 表示 Git 应该
如果文件的 90% 以上,则将删除/添加对视为重命名
没有改变。如果没有 % 符号,该数字将被读取为
分数,前面有小数点。即,-M5 变为 0.5,并且
因此与 -M50% 相同。同样,-M05-M5% 相同。到
将检测限制为精确重命名,请使用 -M100%。默认相似度
指数为50%。

To diff across a rename of a specific file, use -M -- <old-path> <new-path> (-C also works).

So if you both renamed and changed a file in the last commit, you can see the changes with:

git diff HEAD^ HEAD -M -- a.txt test/a.txt

This produces:

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 lines added to help git detect the rename)


If git isn't detecting the rename, you can specify a low similarity threshold with -M[=n], say 1%:

git diff HEAD^ HEAD -M01 -- a.txt test/a.txt

From the git diff docs:

-M[<n>]
--find-renames[=<n>]

Detect renames. If n is specified, it is a threshold on the similarity index (i.e. amount of addition/deletions
compared to the file's size). For example, -M90% means Git should
consider a delete/add pair to be a rename if more than 90% of the file
hasn't changed. Without a % sign, the number is to be read as a
fraction, with a decimal point before it. I.e., -M5 becomes 0.5, and
is thus the same as -M50%. Similarly, -M05 is the same as -M5%. To
limit detection to exact renames, use -M100%. The default similarity
index is 50%.

老娘不死你永远是小三 2024-12-16 20:31:41

您还可以执行以下操作:

git diff rev1:file1 rev2:file2

,对于您的示例,这将是

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

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

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

You can also do:

git diff rev1:file1 rev2:file2

which, for your example, would be

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

Note the explicit ./ -- this format otherwise assumes the paths to be relative to the root of the repo. (If you're in the root of the repo, you can of course omit that.)

This doesn't depend on the rename detection at all, as the user is explicitly stating exactly what to compare. (Therefore, it also comes in handy in some other circumstances, such as comparing files between different svn branches in a git-svn environment.)

守不住的情 2024-12-16 20:31:41

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

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

Git 版本 1.6 及更高版本可以使用更方便的“暂存”标志:

git diff --staged -M -- path/to/file.txt path/to/renamed_file.txt

相同的命令也可以与 git difftool 一起使用,以启动您的第三个-party 视觉 diff 工具(您必须首先配置):

git difftool --tool=p4merge --staged -M -- file.txt file_renamed.txt

如果您想对历史 Git 提交中的重命名文件进行 diff,请使用此:

git diff SHA_ID^ SHA_ID -- path/to/file.txt path/to/renamed_file.txt
Example:
git diff 90e404f3ab332e696e36a3630206bd837925c0f4^ 90e404f3ab332e696e36a3630206bd837925c0f4 -- project/file.txt project/file_renamed.txt

或使用 difftool:

git difftool --tool="meld" 90e404f3^ 90e404f3 -- project/file.txt project/file_renamed.txt

您可以检索重命名的文件更容易像这样:

git diff 90e404f3^ 90e404f3

结果:

diff --git a/file.txt b/file_renamed.txt
...   
rename from project/file.txt
rename to project/file_renamed.txt

If your rename commit is staged but not committed yet, you can use:

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

Git version 1.6 and above can use the more convenient "staged" flag:

git diff --staged -M -- path/to/file.txt path/to/renamed_file.txt

The same commands also work with git difftool, to launch your third-party visual diff tool (which you have to configure first):

git difftool --tool=p4merge --staged -M -- file.txt file_renamed.txt

If you want to do a diff of a renamed file, which is in a historical Git commit in the past, use this:

git diff SHA_ID^ SHA_ID -- path/to/file.txt path/to/renamed_file.txt
Example:
git diff 90e404f3ab332e696e36a3630206bd837925c0f4^ 90e404f3ab332e696e36a3630206bd837925c0f4 -- project/file.txt project/file_renamed.txt

or using difftool:

git difftool --tool="meld" 90e404f3^ 90e404f3 -- project/file.txt project/file_renamed.txt

You can retrieve the paths of the renamed file more easily like this:

git diff 90e404f3^ 90e404f3

Result:

diff --git a/file.txt b/file_renamed.txt
...   
rename from project/file.txt
rename to project/file_renamed.txt
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文