这可能与通常的问题相反:我want Git比实际更积极地进行重命名检测。
$ git init demo
Initialized empty Git repository in …/demo/.git/
$ cd demo
$ echo '#include b' > a
$ (for x in {00..99}; do echo $x; done) > b
$ git add a b
$ git commit -m initial
[master (root-commit) …] initial
2 files changed, 101 insertions(+)
create mode 100644 a
create mode 100644 b
$ git rm a
rm 'a'
$ git mv b a
$ git commit -m inlined
[master …] inlined
2 files changed, 100 insertions(+), 101 deletions(-)
delete mode 100644 b
$ git show -p
commit … (HEAD -> master)
Author: …
Date: …
inlined
diff --git a a
index …..… 100644
--- a
+++ a
@@ -1 +1,100 @@
-#include b
+00
+01
+02
+03
+04
+05
…
+95
+96
+97
+98
+99
diff --git b b
deleted file mode 100644
index …..0000000
--- b
+++ /dev/null
@@ -1,100 +0,0 @@
-00
-01
-02
-03
-04
-05
…
-95
-96
-97
-98
-99
是否有某种方式可以按照我的意图显示此更改—删除a
并结合从b
到a
的功能,但是作为原子提交,因为中间状态无效?
特别是我在乎GitHub如何出于代码审查的目的呈现此内容。
更一般地说,我可能会在移动之后稍稍编辑大文件(占行的一小部分),我希望diff仅在移动顶部显示那些编辑,如Git会自动执行它没有碰巧被重命名为以前存在的文件路径。实际上,真正的编辑会在噪音中丢失。
[不幸的是,没有:Git(和GitHub的)重命名检测是基于左侧提交中的文件名根本找不到,而右侧提交中的某些文件在左侧提交中完全找不到。
也就是说,如果我们有这个:
left right
----- -----
fileA fileA
fileB
fileC
fileD fileD
然后仅有的重命名候选者是
手动运行git diff
(或git show
或内部调用git diff
的任何内容时,您可以添加-B
选项,如果使用文件足够不同。2因此,在命令行上,您可能可以实现所需的功能。但是GitHub不提供-B
选项。
1也就是说,Git在这一点上关注的是identity的形而上学问题。参见the Ship of Theseus。某个文件的版本X是否与该文件的版本Y“相同”?我们怎么知道?
2 -B
选项采用两个数字,两个数字最终都表示为相似性指标百分比。如果两个文件内容的相似性索引低于阈值,则首先将基于名称的初始配对初步分成单独的“删除旧的左侧文件”和“添加新的右侧文件”。如果启用了-M
(可能通过diff.renames
,现在默认为true而不是默认false),它们将成为重命名检测的候选对象。如果重命名检测不能消除一对或其中之一,除非相似性索引降至第二个阈值(通常更宽松)的阈值以下,否则它们将重新加入。
-B
数字参数是用dis而不是相似性表示的,但是文件F的版本X与文件F的版本Y的相异仅是100减去相似度。