强制Git显示删除+以删除+重命名而不是编辑+删除的方式移至已删除的路径

问题描述 投票:0回答:1

这可能与通常的问题相反:我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并结合从ba的功能,但是作为原子提交,因为中间状态无效?

特别是我在乎GitHub如何出于代码审查的目的呈现此内容。

更一般地说,我可能会在移动之后稍稍编辑大文件(占行的一小部分),我希望diff仅在移动顶部显示那些编辑,如Git会自动执行它没有碰巧被重命名为以前存在的文件路径。实际上,真正的编辑会在噪音中丢失。

git
1个回答
0
投票

[不幸的是,没有:Git(和GitHub的)重命名检测是基于左侧提交中的文件名根本找不到,而右侧提交中的某些文件在左侧提交中完全找不到。

也就是说,如果我们有这个:

left        right
-----       -----
fileA       fileA
fileB
            fileC
fileD       fileD

然后仅有的重命名候选者是。文件被认为是“同一文件”(配对或“标识为”动词1因为它们具有相同的路径名,并且文件也已通过名称标识,仅B和C未配对。

手动运行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减去相似度。

© www.soinside.com 2019 - 2024. All rights reserved.