“补丁”是否适用于非对称上下文?

“补丁”是否适用于非对称上下文?

我有文件a

This
file
does
have
an error
in it
that
needs
to be
fixed.

和一个类似的文件b

This
file
does
have
no error
in it
that
needs
to be
fixed.

我可以使用以下命令创建统一的差异diff -u a b

--- a   2018-01-03 14:20:22 +0100
+++ b   2018-01-03 14:20:37 +0100
@@ -2,7 +2,7 @@
 file
 does
 have
-an error
+no error
 in it
 that
 needs

我还可以使用以下命令将上下文减少到两侧的一行diff -u1 a b

--- a   2018-01-03 14:20:22 +0100
+++ b   2018-01-03 14:20:37 +0100
@@ -4,3 +4,3 @@
 have
-an error
+no error
 in it

这两个补丁都可以用 干净地应用patch。然而,我没有找到一种方法来生成diff具有不对称上下文的补丁。我假设它不能做到这一点。因此,我尝试手动删除一些上下文,以在更改之前和之后制作一个包含两行上下文的补丁:

--- a   2018-01-03 14:20:22 +0100
+++ b   2018-01-03 14:20:37 +0100
@@ -3,4 +3,4 @@
 does
 have
-an error
+no error
 in it

这对我来说似乎是有效的统一格式。然而,patch抱怨它不得不诉诸模糊测试:

patching file a
Hunk #1 succeeded at 3 with fuzz 1.

我是否做错了什么,或者(GNU)patch实际上因不对称上下文而被破坏,因为没有人想象它们会被使用,因为diff无论如何都无法制造它们?

同样有趣的是,如果我扭转不对称性,即前面一行和后面两行,则该补丁会起作用:

--- a   2018-01-03 14:20:22 +0100
+++ b   2018-01-03 14:20:37 +0100
@@ -4,4 +4,4 @@
 have
-an error
+no error
 in it
 that

答案1

POSIX标准不提供生成非对称上下文的方法。在一种情况下,GNU 补丁通过接受格式错误的补丁来提供帮助。

顺便说一句,问题中指出的手册页做出了错误的陈述:

目前,只有 GNU diff 可以生成这种格式,并且只有 GNU patch 可以自动应用这种格式的 diff。为了正确操作,补丁通常需要至少三行上下文。

错误仍然在扩散剂信息文件

POSIX 补丁处理统一差异。

答案2

GNUpatch只是不喜欢前缀上下文多于后缀上下文。一个简单但丑陋的解决方法是将上下文的第一行转换为无操作更改,如下所示:

--- a   2018-01-03 14:20:22 +0100
+++ b   2018-01-03 14:20:37 +0100
@@ -3,4 +3,4 @@
-does
+does
 have
-an error
+no error
 in it

这会删除所有前缀上下文。当后缀上下文较多时就可以了。

我确实浏览了patch源代码并发现了有问题的作品。在没有深入理解的情况下,我想出了一个简单的修复方法,类似于代码中已经处理前缀上下文的方式。这是我的输出git diff(的补丁patch):

diff --git a/src/patch.c b/src/patch.c
index bba7e0e..e661af1 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -1171,7 +1171,7 @@ locate_hunk (lin fuzz)
     else if (prefix_fuzz < 0)
       prefix_fuzz = 0;

-    if (suffix_fuzz < 0)
+    if (suffix_fuzz < 0 && pch_first () + pat_lines > input_lines)
       {
    /* Can only match end of file.  */
    offset = first_guess - (input_lines - pat_lines + 1);
@@ -1184,6 +1184,8 @@ locate_hunk (lin fuzz)
    else
      return 0;
       }
+    else if (suffix_fuzz < 0)
+      suffix_fuzz = 0;

     min_offset = max_pos_offset < 0 ? first_guess - max_where
           : max_neg_offset < 0 ? first_guess - min_where
diff --git a/tests/asymmetric-hunks b/tests/asymmetric-hunks
index d6979d9..86e4ef9 100644
--- a/tests/asymmetric-hunks
+++ b/tests/asymmetric-hunks
@@ -77,5 +77,4 @@ seq 1 5 > a

 check 'patch < a.diff' <<EOF
 patching file a
-Hunk #1 succeeded at 2 with fuzz 1.
 EOF

正如 @Patrick Mevzek 指出的,已经有针对非对称上下文的回归测试。因此,这也被纠正为不期望模糊测试。不幸的是,合并测试在一种情况下也失败了,我不知道为什么。我想我因此无法提交补丁。如果有更多洞察力的人能够提出更好的解决方案,那就太好了。

相关内容