外部的合并与比较工具
虽然 Git 自己内置了一个 diff 实现,而且到目前为止我们一直在使用它,但你能够用一个外部的工具替代它。
除此以外,你还能设置一个图形化的工具来合并和解决冲突,从而不必自己手动解决。
这里我们以一个不错且免费的工具 —— Perforce 图形化合并工具(P4Merge) —— 来展示如何用一个外部的工具来合并和解决冲突。
P4Merge 可以在所有主流平台上运行,所以安装上应该没有什么困难。
在这个例子中,我们使用的路径名可以直接应用在 macOS 和 Linux 上;
在 Windows 上,/usr/local/bin 需要被改为你的环境中可执行文件所在的目录路径。
首先, 从Perforce 下载 P4Merge。
接下来,你要编写一个全局包装脚本来运行你的命令。
我们会使用 Mac 上的路径来指定该脚本的位置,在其他系统上,它将是 p4merge 二进制文件所在的目录。
创建一个名为 extMerge 的脚本包装 merge 命令,让它把参数转发给 p4merge 二进制文件:
$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/p4merge.app/Contents/MacOS/p4merge $*
包装 diff 命令的脚本首先确保传递了七个参数过来,随后把其中两个转发给包装了 merge 的脚本。
默认情况下, Git 传递以下参数给 diff:
path old-file old-hex old-mode new-file new-hex new-mode
由于你仅仅需要 old-file 和 new-file 参数,由包装 diff 的脚本来转发它们吧。
$ cat /usr/local/bin/extDiff
#!/bin/sh
[ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"
你也需要确保这些脚本具有可执行权限:
$ sudo chmod +x /usr/local/bin/extMerge
$ sudo chmod +x /usr/local/bin/extDiff
现在你可以修改配置文件来使用你自定义的合并和比较工具了。
这将涉及许多自定义设置:merge.tool 通知 Git 该使用哪个合并工具, mergetool..cmd 规定命令运行的方式,mergetool..trustExitCode 会通知 Git 程序的返回值是否表示合并操作成功,diff.external 通知 Git 该用什么命令做比较。
因此,你可以运行以下四条配置命令:
$ git config --global merge.tool extMerge
$ git config --global mergetool.extMerge.cmd \
'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
$ git config --global mergetool.extMerge.trustExitCode false
$ git config --global diff.external extDiff
或编辑你的 ~/.gitconfig 文件,添加以下各行:
[merge]
tool = extMerge
[mergetool "extMerge"]
cmd = extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
trustExitCode = false
[diff]
external = extDiff
待一切设置妥当后,如果你像这样运行 diff 命令:
$ git diff 32d1776b1^ 32d1776b1
Git 将启动 P4Merge,而不是在命令行输出比较的结果,就像这样:
Figure 143. P4Merge.
如果你尝试合并两个分支,随后遇到了合并冲突,运行 git mergetool,Git 会调用 P4Merge 让你通过图形界面来解决冲突。
设置包装脚本的好处在于大大降低了改变 diff 和 merge 工具的工作量。
举个例子,想把 extDiff 和 extMerge 的工具改成 KDiff3,你要做的仅仅是编辑 extMerge 脚本文件:
$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/kdiff3.app/Contents/MacOS/kdiff3 $*
现在,Git 将使用 KDiff3 作为查看比较和解决合并冲突的工具。
Git 预设了许多其他的合并和解决冲突的工具,无需特别的设置你就能用上它们。
要想看到它支持的工具列表,试一下这个:
$ git mergetool --tool-help
'git mergetool --tool=' may be set to one of the following:
emerge
gvimdiff
gvimdiff2
opendiff
p4merge
vimdiff
vimdiff2
The following tools are valid, but not currently available:
araxis
bc3
codecompare
deltawalker
diffmerge
diffuse
ecmerge
kdiff3
meld
tkdiff
tortoisemerge
xxdiff
Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.
如果你不想用到 KDiff3 的所有功能,只是想用它来合并,那么 kdiff3 正符合你的要求,运行:
$ git config --global merge.tool kdiff3
如果运行了以上命令,而没有设置 extMerge 和 extDiff 文件,Git 会用 KDiff3 做合并,让内置的 diff 来做比较。