是否有任何标准选项来创建对文件 F 起作用的“补丁”P,以便当文件 F 更改为 F' 时它将继续正常工作。
因此,我要么有某种机制将 P 更改为 P',以便 P'(F') 产生与 P(F) 相同的变化,或者,最好我将有弹性 P,以便它可以用于 F & F'。
目前我正在使用正则表达式搜索和替换来创建此类补丁,但我想知道是否有任何标准方法可以执行此类操作。
答案1
我真的不建议使用sed
这样的东西。问题是,即使应用了补丁,它通常也会出现“模糊”——这意味着某些上下文行并不完美匹配。虽然这通常意味着底层周围的代码发生了轻微的变化,但它也可能意味着补丁应用在错误的地方(我已经看到这种情况发生,它不好而且不容易调试)。
此外,即使补丁应用干净,它也可能在语义上不再有意义。然而,要抓住这一点,您必须了解修补代码中发生的更改。
出于所述原因,至少审查任何适用于模糊的内容被认为是一种良好的做法(并且可能还表面上检查适用于偏移的任何内容)。拥有超过默认的 3 行上下文可能也是一个好主意。
在经历了大胖警告之后,相对轻松地做到这一点的方法之一是使用版本控制系统,可能是一种先进的分布式系统,例如mercurial
或者git
。关于这两者之间的选择的意见各不相同,Mercurial 比 Git 更类似于旧的 CVS 和 SVN,并且可以说也有更好的学习曲线(Whikle Git 据称功能更丰富)。
在 Mercurial 中有Mercurial 队列 (MQ) 扩展正是针对这些情况。这是史蒂夫·洛什的博客文章是关于使用 MQ 的相当不错的介绍,另一本不错的读物是MQ 指南在 Mozilla 的开发者网站上。
有时,patchutils
也能派上用场。
答案2
这个问题称为合并。您有一个原始文件 A 和两个修改版本 B 和 C,并且您想要制作一个结合了这两个修改的版本 D。仅当更改是独立的时,这才有效;否则,合并是一个手动过程。处理源代码并发更改的合并是软件工程中的一项常见任务。
diff
在简单的情况下,如果源文件发生了更改,由 生成的补丁就已经可以工作了。该patch
实用程序允许一些“模糊”:如果您从 A 到 B 进行比较,并且受该差异影响的区域在 A 和 C 中是相同的(但可能在文件中的偏移量不同),则补丁将干净地应用在 C 上只要 B 和 C 中的更改区域不在同一位置(必须有几行分隔),这种方法就可以正常工作。
当补丁应用不彻底时,合并就是一个困难且特定于领域的问题。例如,考虑以下两个更改:
A B C
a=2 a=3 b=2
x=a x=a x=b
人类倾向于发现 B 已更改2
为3
且 C 已重命名a
为的模式b
,因此合并的结果应该是b=3
, x=b
。但自动化工具可能会将第一行标记为冲突,因为它已以两种不同的方式进行了修改。
编写一个对 B 和 C 都“做一些明智的事情”的补丁是一个困难的(人工智能完整的)问题。在实际情况中,对于许多典型情况,使用diff -u A B
as 补丁往往要么工作并从 C 中产生所需的 D,要么失败并出现错误,表明补丁应用不干净。