Применить несколько патчей, чтобы получить накопленные изменения
У меня есть базовый исходный файл 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"
=>
extended.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
).
НЕ РАБОТАЕТ
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
но это работает только в том случае, если патчи были применены в последовательном порядке, следовательно, мне нужно было бы произвести diff из base_foo.hs
,
diff3?
Diff + patch - сумма вместо замены относится к 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
(очевидно, он выдает большой конфликтный файл, включающий все три версии)
разное?
У меня также была идея использовать инструменты слияния SCM, такие как git, но, очевидно, их можно использовать только для коммитов, но мои файлы не контролируются версиями.
Мое текущее решение вставляет фрагменты кода через perl -pi -e
но это довольно трудоемко и подвержено ошибкам.
1 ответ
# 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!