1

我有一系列 .patch 文件需要应用于某些代码,但我没有这些补丁所基于的原始来源。

我一直在使用“git apply”应用它们,但它没有应用所有更改(这是一个单独的问题)。

如果我所有的 .patch 文件都被压缩成一个大补丁,我会更容易调试“git apply”(或手动应用它们)的问题。不幸的是,我在这个站点上找到的所有答案都假设您可以在补丁所基于的原始源上运行 git 命令,而我不能。

我也知道补丁的顺序。

有没有办法在没有原始来源的情况下将多个补丁文件“压缩”成一个补丁?如果您需要任何额外信息,请告诉我。

这是我认为可以压缩的两个补丁文件的示例:

$ cat patch1.patch
diff --git a/foo.c b/foo.c
index ...
--- a/foo.c
--- b/foo.c
@@ -1,2 +1,3 @@
 int main(){
+printf("1");
 }
$ cat patch2.patch
diff --git a/foo.c b/foo.c
index ...
--- a/foo.c
--- b/foo.c
@@ -1,3 +1,4 @@
 int main(){
 printf("1");
+printf("2");
 }
$ merge-patches patch1.patch patch2.patch > patch1and2.patch # this command doesn't exist, but I want it to
$ cat patch1and2.patch
diff --git a/foo.c b/foo.c
index ...
--- a/foo.c
--- b/foo.c
@@ -1,2 +1,4 @@
 int main(){
+printf("1");
+printf("2");
 }
4

1 回答 1

1

有没有办法在没有原始来源的情况下将多个补丁文件“压缩”成一个补丁?

在完全一般的情况下,没有。幸运的是,您没有完全一般的情况。

一个非常简单的“补丁代数”适用于简单的情况。例如,假设我们担心单个文件。补丁 A 说“在第 3 行之后添加两行”,补丁 B 说“在第 10 行之后添加一行”。如果补丁 A 在补丁 B 之前,我们可以将它们组合成一个补丁,上面写着“在第 3 行之后添加这两行,在第 8 行之后添加另一行”,因为我们知道补丁 B 中的第 10 行必须是行补丁 A 中的 8,因为补丁 A 增加了两行,都在第 8 行之前。

如果两个补丁以另一个顺序排列,则组合补丁需要在位置 3 和 10 处添加行,而不是在位置 3 和 8。当补丁重叠时,情况会变得相当丑陋,但即使你不这样做,你仍然可以让某些情况工作'不知道正确的顺序,因为上下文可能提供正确的顺序。

我也知道补丁的顺序。

这很有帮助,因为现在我们肯定知道 A 在 B 之前:无需根据上下文进行猜测。

所以,当后来的补丁修改了之前的补丁,并且我们知道它们都适用于一个固定的初始基础时,我们可以将它们组合起来,只要我们知道顺序。这可能会丢失信息(即,在组合之前,您可能能够找到真正的基本修订;组合之后,您可能不再能够做到这一点)。1 如果您对此感到满意,您可以编写一个程序来执行此操作。我不知道有任何现有的程序可以做到这一点,尽管 DARCS 是用补丁代数的概念构建的,因此是一个候选程序。你可以看看http://darcs.net/Theory(我自己没怎么看)。


1我还没有为此构建一个证明,但直觉上很明显......这意味着它可能是完全错误的。

于 2020-10-07T09:50:44.730 回答