处理合并时的二进制文件

作者:Ryan Wilcox
日期:2009-11-30

大部分时间我们都在同文本文件和源代码等打交道,但有时我们会把二进制文件放进我们的代码库中,这时处理那些不可避免的合并冲突并不像源代码那么容易。

假设你搭建了一个网站并且你为这个网站保留了一张图片在 Mercurial 的库中。最后有两个人同时试图去修改那个图片,于是产生了一个合并冲突。

为 Mercurial 设置不同的合并工具

在你的 ~/.hgrc 文件中,你应该添加以下段:

[merge-tools]
diff_images.args = $output $other

[merge-patterns]
**.png = diff_images

现在,创建一个 diff_images 的 shell 脚本,将其设置为可执行的,然后放到你的 $PATH 中去。我的像是这样:

open -a GraphicConverter $1 $2 -W
# opens the first and second parameter with GraphicConverter, waiting
# until same is quit before letting the shell continue.

现在如果一个合并包含了有 .png 文件的冲突都将会打开 GraphicConverter 。这将会打开两张图片:一张是现在在你的源码树上的,而另一张是来自 Mercurial 的。你能够区分出它们的不同,因为来自 Mercurial 的那一张在文件扩展名后面还跟有一串随机字符。例如,你的冲突文件名为 image.png , GraphicConverter 会打开两个窗口: images.pngimage.png~other.bQkQxd

手动的将新文件中的变更加到原来的文件中去 (image.png),做好后保存原来的那份并退出 GraphicConverter ,这样变更就会被提交了。

这个设置是怎么工作的

首先, diff_images.args 设置了两个参数传给图像处理工具:

  • $output 是 Mercurial 将会提交的文件,并且包含了第一个父亲的版本
  • $other 是你要合并的那个修订的版本

这里还有其他 .args 参数提供的选项:

  • $local$output 的一份拷贝,但是此文件的变更都会在合并时被忽略
  • $base 是出现文件内容冲突之前的正常修订中的文件

你可以使用这些来设置一个三路合并,如果需要的话,或是增强 diff_images 来向用户展示合并 之前 发生混乱的文件的内容。

接下来, [merge-patterns] 段表明了当一个文件名匹配上了指定的模式时应该使用哪个合并工具。

如果没有 merge-pattern 段的话, diff_images 会考虑一个 diff 候补,但这会被忽略掉因为 Mercurial 会认为 diff_images 没能力处理产生 diff 的二进制文件。向 [merge-patten] 添加行告诉 Mercurial diff_images 能够处理指定的文件类型。

代替加入 merge-patterns 段,你也可以添加一行内容,类似 diff_images.args ,告诉 Mercurial diff_images 能够处理好二进制文件: diff_images.binary = True

不管怎么说,这会让 diff_images 在 GraphicConverter 不能胜任的时候从 所有的 二进制 diff 工具中选一个候选者出来(比如,选择 GraphicConverter 对 mp3 进行 diff 可不是什么好主意)。

当发生非常糟糕的错误时:终止合并

合并 能够被终止时可以使用 hg revert 这一手段,当你尝试它后会得到:

$ hg revert --all
abort: uncommitted merge - please provide a specific revision

但你仅仅只是想清除掉你的合并工作并从擦除处再开始工作而已,那再使用 hg update --clean