使用 git 删除函数及其文档块时如何创建适当的补丁

ale*_*tes 5 git

当您在多个函数之上有 docblocks 时,删除一个函数会创建一个次优补丁。

索引.js:

/**
 * Function foo description.
 */
function foo() {}

/**
 * Function bar description.
 */
function bar() {}
Run Code Online (Sandbox Code Playgroud)

删除函数 foo 及其文档块会生成以下补丁:

diff --git a/index.js b/index.js
index f4e18ef..933004f 100644
--- a/index.js
+++ b/index.js
@@ -1,9 +1,4 @@
 /**
- * Function foo description.
- */
-function foo() {}
-
-/**
  * Function bar description.
  */
 function bar() {}
Run Code Online (Sandbox Code Playgroud)

这意味着任何合并带来的提交触及函数 foo 和函数 bar 之间的空间现在都会导致冲突。例如,假设我们feature-1在删除 foo 之前创建了一个分支,并在两者之间index.js添加了一个函数foobar。冲突如下:

/**
<<<<<<< HEAD
=======
 * Function foo description.
 */
function foo() {}

/**
 * Function foobar description.
 */
function foobar() {}

/**
>>>>>>> feature-1
 * Function bar description.
 */
function bar() {}
Run Code Online (Sandbox Code Playgroud)

我想如果/**从顶部抓起它就不会有问题。我确信 git 有一个很好的理由更喜欢从最后删除,但我想强迫它从一开始就抓住它。有没有办法轻松做到这一点?还是手动补丁编辑是唯一的方法?

tor*_*rek 3

它远非完美,但--compaction-heuristicGit 2.9 中的新功能通常可以满足您的需求。有关详细信息,请参阅此博客文章。您可以将其配置为默认打开,但考虑到它有时会使事情变得更糟,我没有这样做:

git config --global diff.compactionHeuristic true
Run Code Online (Sandbox Code Playgroud)

您的 Git 版本必须至少为 2.9 才能生效。

当前实现中的一个缺陷是,它实际上需要在修改的部分上方有一个空行。从文件顶部开始是不够的。例如,假设我们从以下开始:

block:
This file has
three blocks.

block:
There is a blank line
between each.

block:
This is the third
block.
Run Code Online (Sandbox Code Playgroud)

如果我们删除中间块,默认 diff 会保留第二block:行并删除第三block:行。打开压缩会向上移动 diff 块,直到到达第二个上方的空白行block:,这就是我们想要的。

不幸的是,如果我们删除第一个块,压缩启发式尝试将 diff 块向上移动以包含第一block:行,但会失败,因为它到达文件的顶部,其上方没有空行(因为没有行)完全高于它)。因此,它会保留第一个单词block:并删除第二个单词。

(解决这个问题只需要压缩算法提供一个空白的“虚拟行零”。请注意,问题本身永远不会发生在文件末尾,因为默认差异有利于删除后面的行。同时,一个丑陋的解决方法是在每个文件的顶部留下一个空行,以便压缩可以看到它。)