Merge 应用多个修补程序以获得累积的更改

Merge 应用多个修补程序以获得累积的更改,merge,diff,patch,diff3,Merge,Diff,Patch,Diff3,我有一个基本源文件base.hs,我使用它创建同一程序的不同扩展版本(foo.hs,bar.hs,baz.hs)。现在我想创建一个补丁文件的每一个修改版本,但补丁应该积累得到一个程序,其中包括所有的扩展名 base.hs -- @@BEGIN_IMPORTS@@ -- @@END_IMPORTS@@ main = do -- @@BEGIN_EXTENSIONS@@ -- @@END_EXTENSIONS@@ putStrLn "Hello World" hs(注意它

我有一个基本源文件
base.hs
,我使用它创建同一程序的不同扩展版本(
foo.hs
bar.hs
baz.hs
)。现在我想创建一个补丁文件的每一个修改版本,但补丁应该积累得到一个程序,其中包括所有的扩展名

base.hs

-- @@BEGIN_IMPORTS@@
-- @@END_IMPORTS@@

main = do
    -- @@BEGIN_EXTENSIONS@@
    -- @@END_EXTENSIONS@@
    putStrLn "Hello World"
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+补丁?

我知道
diff
patch
实用程序,但问题是如果我应用多个补丁,它们会相互抵消(因此我会得到
baz.hs

不起作用

combinediff?

我也知道
combinediff
,但这只在补丁按顺序应用时有效,因此我需要从
base\u foo.hs
生成差异

diff3?

指的是
diff3
实用程序(
patchitils
包),但我似乎没有实现所需的行为,而且我不知道这对多个补丁有什么帮助

不起作用

(这里的想法是从一个空文件中组合差异)

不起作用

(显然,它会生成一个包含所有三个版本的大冲突文件)

杂项?

我还想到了使用诸如git之类的SCM合并工具,但显然它们只能用于提交,但我的文件不在版本控制中

我目前的解决方案是通过
perl-pi-e
插入代码片段,但这相当费力,而且容易出错

# diffs can be created beforehand

diff base.hs foo.hs > foo.hs.diff
diff base.hs bar.hs > bar.hs.diff
diff base.hs baz.hs > baz.hs.diff

# *creating a mybase.hs here which is slightly different (like "Hello Mars")*

# the follow steps need to be done for every run

patch -o myfoo.hs mybase.hs foo.hs.diff
patch -o mybar.hs mybase.hs bar.hs.diff 
patch -o mybaz.hs mybase.hs baz.hs.diff

# we create a temp file here because it seems that merge-file and the stream operator '>'
# operate on the same file immediately
cp mybase.hs mybase_union.hs
git merge-file -p --union myfoo.hs mybase.hs mybase_union.hs         > mybase_union_foo.hs
git merge-file -p --union mybar.hs mybase.hs mybase_union_foo.hs     > mybase_union_foo_bar.hs
git merge-file -p --union mybaz.hs mybase.hs mybase_union_foo_bar.hs > mybase_union_foo_bar_baz.hs
cp mybase_union_foo_bar_baz.hs mybase_extended.hs

Thx armel

您不知道解决方案是应该自动化,还是可以手动。顺便说一句,大多数SCMs合并工具可以在任意文件上执行,一些独立的合并工具也可以(甚至可以从命令行)。要实现自动化,问题在于您希望使用“a然后B”的方法接受冲突文本,但它是否始终适用于文本本身的不同部分?我想提供一些自动应用的修补程序文件,是的。我刚刚找到了“git merge file--union”,这是一个部分解决方案,但它只合并整个文件。这是一个问题,因为我也有不同的文本在文件中,我想忽略@A那么B:我不知道我是否正确理解你,但是,是的,它总是适用的。文本部分互不依赖。如果需要忽略某些行,可以先进行diff(使用一些-I regexp),然后在基础文件上单独应用生成的修补程序,以在每个派生文件上生成一个“简化”文件(因此,此修补结果与基础文件的差异较小),您可以合并这些文件。所有被忽略的部分不会发生冲突,并保持在基本文件中。好主意,这可能会起作用!
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
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
# diffs can be created beforehand

diff base.hs foo.hs > foo.hs.diff
diff base.hs bar.hs > bar.hs.diff
diff base.hs baz.hs > baz.hs.diff

# *creating a mybase.hs here which is slightly different (like "Hello Mars")*

# the follow steps need to be done for every run

patch -o myfoo.hs mybase.hs foo.hs.diff
patch -o mybar.hs mybase.hs bar.hs.diff 
patch -o mybaz.hs mybase.hs baz.hs.diff

# we create a temp file here because it seems that merge-file and the stream operator '>'
# operate on the same file immediately
cp mybase.hs mybase_union.hs
git merge-file -p --union myfoo.hs mybase.hs mybase_union.hs         > mybase_union_foo.hs
git merge-file -p --union mybar.hs mybase.hs mybase_union_foo.hs     > mybase_union_foo_bar.hs
git merge-file -p --union mybaz.hs mybase.hs mybase_union_foo_bar.hs > mybase_union_foo_bar_baz.hs
cp mybase_union_foo_bar_baz.hs mybase_extended.hs