如何使用git合并两个版本的非文本文件?

时间:2018-02-16 21:58:14

标签: git merge binary

我正在开展一个项目,其中各种测试参数存储在LibreOffice .ods电子表格文件中。问题:如果两个开发人员对他们的分支上的.ods文件进行了更改,那么当我们尝试合并时,Git会(不出意料地)沮丧地举手,要求我们选择一个或另一个版本。

我想要做的是在LibreOffice中打开冲突文件的两个源版本,手动将它们编辑为新文件,然后将该新文件签入为“合并”文件。这适用于任何Git-opaque类型的文件,可以在某个专门的编辑器中打开并手动编辑。

我该怎么做?

注1:"Manual File Re-merging"中描述了一个Pro Git book程序,但它似乎仍然假定我们正在处理文本。例如,我没有看到命令git merge-file -p hello.ours.odb hello.common.odb hello.theirs.odb > hello.odb如何使用三个源电子表格文件执行任何智能操作来生成输出电子表格文件。

注2:争论将数据存储在.ods文件中是否明智是没有用的。我们有充分的理由以这种方式存储数据,其中最重要的是“就是这样”。

2 个答案:

答案 0 :(得分:2)

ODF是一种zipped-xml格式;我还没有真正尝试过,但是我发现你可以解压缩文件,例如xmllint --format content.xml并尝试对结果进行文字合并。对于我来说,这是最吸烟的,

set -- `git checkout-index --stage=all path/to/my/foo.ods`
7z x -obase $1
7z x -oours $2
7z x -otheirs $3

find base ours theirs -name \*.xml -execdir xmllint --format {} -o {}.pretty \;

git merge-file {ours,base,theirs}/content.xml.pretty
# or not, but doing the merge-file is helpful, then
vimdiff {ours,base,theirs}/content.xml.pretty

使ours漂亮的版本看起来像你想要的。您必须注意任何媒体文件更改。然后

find ours -name \*.pretty -execdir -rename .pretty '' {} + 
(cd ours;7z -t zip u ../$4 .)

我的libreoffice 6安装打开更新版本就好了。我不知道合并对于大手术是多么可怕,我知道对于我的小单页分类帐,差异看起来正确我所做的更改,并且合并文件的automerge正常工作,标记了冲突并将uns纳入我们的版本。

答案 1 :(得分:1)

  

我想做的是在LibreOffice中打开冲突文件的两个源版本......

这是您出错的地方:没有两个源版本存在冲突,三个源版本,更改(可能会或可能不会发生冲突。)

Git无法自行计算更改,因为它们不是纯文本行。但是Git 可以给你三个文件。这就是custom merge driver的含义。

文件的合并基础版本(上面的链接称为%O,其中O代表原始版本),根据定义,将与本地/左手不匹配/ --ours文件版本(上面的链接指的是%A)。根据定义,它也不会匹配文件的远程/右手/ --theirs版本(上面的链接称为%B)。左右版本也不匹配:这就是为什么需要合并的原因。如果左右版本确实匹配,Git会认为其中任何一个都能同样好用,并且只使用左或右版本(你无法分辨哪一个Git使用,因为它们匹配,bit-for-位!)。

  

...手动将它们编辑成新文件,然后将该新文件签入为"合并"文件。这适用于任何Git-opaque类型的文件,可以在某个专门的编辑器中打开并手动编辑。

实际上你可以做到这一点,即使没有定义自定义合并驱动程序 - 事实上,定义自定义合并驱动程序的唯一一点就是通过软件自动实现这一点,而无需让grubby protuberances进入那里。当合并因合并冲突而停止时,Git已将该文件的所有三个版本保留在索引中,分阶段1(合并基础),2(左/ --ours版本)和3(右/ --theirs版本。)

The git mergetool script包含一个相当复杂的示例,说明如何从索引中提取三个版本中的每一个,然后在提取的文件上运行一些合并工具。请参阅the checkout_staged_file functionits callers。您的工作是提取三个版本,手动合并,然后git add生成的二进制对象作为文件的解析版本。