【发布时间】:2025-12-10 11:20:06
【问题描述】:
我有一个基本源文件base.hs,我使用它来创建同一程序的不同扩展版本(foo.hs、bar.hs、baz.hs)。现在我想为每个修改版本创建一个补丁文件,但补丁应该累积以获得包含所有扩展的程序。
base.hs
-- @@BEGIN_IMPORTS@@
-- @@END_IMPORTS@@
main = do
-- @@BEGIN_EXTENSIONS@@
-- @@END_EXTENSIONS@@
putStrLn "Hello World"
foo.hs(注意它基本上是同一个文件)
-- @@BEGIN_IMPORTS@@
import Foo
-- @@END_IMPORTS@@
main = do
-- @@BEGIN_EXTENSIONS@@
putStrLn foo
-- @@END_EXTENSIONS@@
putStrLn "Hello World"
bar.hs
-- @@BEGIN_IMPORTS@@
import Bar
-- @@END_IMPORTS@@
main = do
-- @@BEGIN_EXTENSIONS@@
putStrLn bar
-- @@END_EXTENSIONS@@
putStrLn "Hello World"
baz.hs
-- @@BEGIN_IMPORTS@@
import Baz
-- @@END_IMPORTS@@
main = do
-- @@BEGIN_EXTENSIONS@@
putStrLn baz
-- @@END_EXTENSIONS@@
putStrLn "Hello World"
=>
扩展的.hs
-- @@BEGIN_IMPORTS@@
import Foo
import Bar
import Baz
-- @@END_IMPORTS@@
main = do
-- @@BEGIN_EXTENSIONS@@
putStrLn foo
putStrLn bar
putStrLn baz
-- @@END_EXTENSIONS@@
putStrLn "Hello World"
差异 + 补丁?
我知道diff 和patch 实用程序,但问题是如果我应用多个补丁,它们会相互抵消(因此我会得到baz.hs)。
不工作
diff -c base.hs foo.hs > foo.hs.c3
diff -c base.hs bar.hs > bar.hs.c3
diff -c base.hs baz.hs > baz.hs.c3
patch -o base_foo.hs base.hs foo.hs.c3
patch -o base_foo_bar.hs base_foo.hs bar.hs.c3
patch -o base_foo_bar_baz.hs base_foo_bar.hs baz.hs.c3
combinediff?
我也知道combinediff,但这仅适用于按顺序应用补丁的情况,因此我需要从base_foo.hs 生成差异。
diff3?
Diff + patch - Sum instead of replace 指的是diff3 实用程序(patchutils 包),但我似乎没有让所需的行为正常工作,而且我不知道这对多个补丁有何帮助。
不工作
touch null
diff3 foo.hs.c3 null bar.hs.c3 > foo_bar.hs.c3
patch -o base_foo_bar.hs base.hs foo_bar.hs.c3
(这里的想法是结合空文件中的差异)
不工作
diff3 -m foo.hs.c3 base.hs bar.hs.c3 > base_foo_bar.hs
(显然它会产生一个包含所有三个版本的大冲突文件)
杂项?
我也有过使用 git 等 SCM 的合并工具的想法,但显然它们只能用于提交,但我的文件不受版本控制。
我目前的解决方案是通过perl -pi -e 插入代码 sn-ps,但这相当费力且容易出错。
【问题讨论】:
-
您不知道解决方案是否应该是自动化的,或者是否可以是手动的。顺便说一句,大多数 SCM 合并工具可以在任意文件上执行,并且一些独立的合并工具可能能够(甚至从命令行)。自动解决问题在于您希望使用“A 然后 B”的方法来接受冲突的文本,但它是否总是适用于文本本身的不同部分?
-
我想提供一些自动应用的补丁文件,是的。我刚刚发现“git merge-file --union”是一个部分解决方案,但它只合并整个文件。这是一个问题,因为我在要忽略的文件中也有不同的文本。 @A 然后 B:我不知道我是否理解正确,但是,是的,它总是适用的。文本部分不相互依赖。
-
如果您需要忽略某些行,您可以先进行比较(使用一些 -I 正则表达式),然后将生成的补丁单独应用于基础文件以生成每个派生的“简化”文件(因此,此修补结果与基本文件的差异较小),您可以合并这些文件。所有被忽略的部分都不会发生冲突并保留在基本文件中。
-
好主意,这可能行得通!