gpt4 book ai didi

git - 在单个文件上使用 git diff 显示重命名/移动状态

转载 作者:行者123 更新时间:2023-12-05 02:32:21 25 4
gpt4 key购买 nike

当我使用 git mv 移动或重命名文件时,git 在全局 diff 输出中显示移动/重命名操作:

me@myhost:~/test$ git mv foo.txt bar.txt
me@myhost:~/test$ git diff --staged
diff --git a/foo.txt b/bar.txt
similarity index 100%
rename from foo.txt
rename to bar.txt

但是,当我在文件上调用 git diff 时,它显示为新文件:

me@myhost:~/test$ git diff --staged bar.txt
diff --git a/bar.txt b/bar.txt
new file mode 100644
index 0000000..fad95f3
--- /dev/null
+++ b/bar.txt
@@ -0,0 +1 @@
+Hey there!

为什么此文件的 git diff 输出会因我是否使用文件名调用它而有所不同?当我传递文件名时,是否有标志或其他方式来查看重命名/移动状态?

Stack Overflow 上的大多数类似问题都建议在调用中添加 --find-renames 参数。不过,这似乎是我的默认行为,因为没有参数的 git diff 已经正确显示了重命名。但是,将 --find-renames 传递给带有文件名的第二次调用并没有什么不同。

最佳答案

请注意,为简单起见,我们假设您提交了更改并正在比较提交;无论您事先使用 --staged 还是之后使用提交,结果都是相同的。

Why is the output of git diff for this file different depending on whether I call it with or without the filename?

将文件规范视为可以通过其查看差异的镜头

当完整地查看这两个提交时,Git 会看到:

  • 提交 1 包含文件名 F1,其内容为哈希 H1 的 blob B1,并且不包含 F2。
  • 提交 2 包含文件名 F2,其内容为哈希 H1 的 blob B1,并且不包含 F1。

Git 看到 F1 和 F2 指向同一个 blob,因为 F1 消失了,而 F2 出现了同一个 blob,Git 可以推断这是一个重命名。如果该文件也被编辑过,Git 可以进行试探法(顺便说一下,这是可配置的),以确定 blob 之间的差异是否足够接近以仍将其称为重命名。

当通过文件名镜头查看两个提交时,Git 看到:

  • 提交 1 不包含 F2。
  • 提交 2 包含文件名 F2,其内容为哈希 H1 的 blob B1。

Git 将此视为添加。

你能做什么?

您可以将镜头放大以包含两个文件名。使用您的示例语法进行移动,请考虑以下语句:

git diff --staged -- foo.txt # specify only the old file shows a delete
git diff --staged -- bar.txt # specify only the new file shows an add
git diff --staged -- foo.txt bar.txt # specify both shows a rename

或者在你提交之后,这里是比较当前和之前提交的类似语法:

git diff @~1 @ -- foo.txt # specify only the old file shows a delete
git diff @~1 @ -- bar.txt # specify only the new file shows an add
git diff @~1 @ -- foo.txt bar.txt # specify both shows a rename

这样做的明显缺点是您还必须知道以前的名字。根据您最终要实现的目标,也许您可​​以将多个命令链接在一起以解析前后文件名,并将它们都用作差异文件规范。下面是一个示例起点,向您展示了仅针对全局镜头的重命名:

git diff --staged --name-status -R
# or
git diff @~1 @ --name-status -R

这可能会导致你做这样的事情(使用 Bash):

git diff --staged -- $(echo $(git diff --staged --name-status -R | grep bar.txt) | cut -d' ' -f 2-)
# or
git diff @~1 @ -- $(echo $(git diff @~1 @ --name-status -R | grep bar.txt) | cut -d' ' -f 2-)

这是一个很棒的question and answer详细信息 diff filter options .

关于git - 在单个文件上使用 git diff 显示重命名/移动状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71268388/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com