如何将WinMerge设置为我的git合并工具?

69

我正在尝试将WinMerge与Git集成,就像我之前在Windows 7 Ultimate上看到的其他人所做的那样。

我按照以下步骤进行了操作,但当我执行git mergetool命令时,仍然会出现错误,该命令默认使用vimdiff。

在git的根目录C/Program Files (x86)/Git/中创建一个名为winmerge.sh的文件,并写入:WinMergeU是正确的位置。

#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"C:/Program Files (x86)/WinMerge/WinMergeU.exe" 
git /e /u /dl "Base" /dr "Mine" "$1" "$2"

然后使用了以下命令。

git config --global diff.tool winmerge
git config --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
git config --global difftool.prompt false

错误显示为:

git config option merge.tool set to unknown tool: winmerge

2
你的 $PATH 中是否有 winmerge.sh?你使用了什么命令导致出现这个错误(错误显示为:git config option merge.tool set to unknown tool: winmerge)? - positron
注意:使用Git 2.5+(2015年第二季度)后,Winmerge 将成为一种已知的差异或合并工具!请参见 下面的答案 - VonC
16个回答

80
你正在谈论“合并工具”,然而你(和一些其他有答案的人)正在将其配置为“差异工具”。
要配置合并工具,您需要使用merge.tool和mergetool配置,而不是diff.tool和difftool,就像这样:
git config --global merge.tool winmerge
git config --replace --global mergetool.winmerge.cmd "\"C:\Program Files (x86)\WinMerge\WinMergeU.exe\" -e -u -dl \"Base\" -dr \"Mine\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\""
git config --global mergetool.prompt false

然后你可以使用

git mergetool

这将打开两个文件以进行编辑。

感谢@dvdvck在评论中提到,您可以在命令行参数中为winmerge指定第三个文件作为结果文件(outputpath参数)。

为了完整起见,我还要提到这个代码片段,旨在完全配置winmerge作为差异和合并工具。


4
在WinMerge链接中,它说它只支持通过命令行进行三方合并,因此对于Git的目的来说,这是可以的。 - dvdvck
6
根据你使用的不同shell(例如bash),转义* $LOCAL $REMOTE $MERGED *可能无法在.gitconfig中产生正确的结果,你可以手动编辑它,但除此之外以上内容都能很好地工作。 - Andrew Theken
为了详细说明@AndrewTheken的评论:上述针对mergetool.winmerge.cmd的配置命令在Windows命令提示符(cmd.exe)中可以正确使用,但在Bash中会因变量扩展而产生错误的配置,或者在Powershell中甚至无法运行,因为路径中有(x86)部分。 - Sergii Volchkov
1
要在Powershell中使其工作,只需用单引号替换最外层的双引号即可。 - lesscode
4
是的(cc @RZKY),在Windows的bash中执行此操作时,我还必须转义$符号。没关系。我发现使用MERGED文件比REMOTE更容易。我执行了:git config --global mergetool.winmerge.cmd "\"c:\\program files (x86)\\winmerge\\winmergeu.exe\" -e -u -dl \"Base\" -dr \"Mine\" \"\$LOCAL\" \"\$MERGED\" \"\$REMOTE\""--与答案相同,只是用了\$,并交换了MERGED / REMOTE。然后它就可以工作了。(PS我也惊喜地发现,即使从bash中,本地路径名也可以正常工作,而不是/c/Prograblahblah...)。 - Jason C
显示剩余4条评论

41

如果你决定使用SourceTree(或任何搜索SourceTree的人),你可以通过将Merge Tool设置为custom,将Diff Command指向WinMergeU.exe来使用WinMerge作为合并工具,通常是:

C:\Program Files (x86)\WinMerge\WinMergeU.exe

在参数中使用:

-e -u -dl "Mine" -wr -dr "Theirs" $LOCAL $REMOTE $MERGED

这将导致左侧(标记为“Mine”)可编辑,并且在WinMerge中保存时它将是输出文件。右侧(标记为“Theirs”)将是只读的(这是-wr参数),因为WinMerge将所有保存的文件输出到$MERGED文件,所以如果两侧都被编辑,它会先输出左侧文件,然后用右侧文件覆盖它;最好避免这种混淆。

如果您保留备份文件选项,WinMerge将生成一个.bak文件。该文件的内容将是原始的左侧文件,或者如果您保存多次,则为倒数第二个输出文件。您可以关闭此选项,或将*.bak添加到您的.gitignore文件中。

Git本身将在冲突解决后创建一个*.orig冲突文件,以防万一出错。同样,您可以将*.orig添加到您的.gitignore文件中,或关闭此功能。不幸的是,SourceTree没有此GUI选项,因此请启动git bash或(如果您在安装期间选择了正确的PATH选项)Windows命令提示符并执行以下操作:

git config --global mergetool.keepBackup false

这将阻止Git创建*.orig文件。您还可以通过找到位于用户目录根目录中的.gitconfig文件直接编辑配置文件。如果您知道如何使用VIM,可以使用以下命令编辑整个内容:

git config --global --edit

1
这里还有另一组命令行选项:https://community.atlassian.com/t5/Questions/Can-t-launch-external-merge-tool-WinMerge-on-Windows/qaq-p/315156它们的作用相同,只是在WinMerge中布局略有不同。 - Eric Burdo

38

Git 2.5+(2015年第二季度)将包含Winmerge作为已知的{{link1:git mergetool}}!

如果Winmerge在您的% PATH%中,则只需执行 git config merge.tool winmerge 即可!
(对于diff工具也有效: git config diff.tool winmerge

查看 提交 3e4f237,作者为David Aguilar (davvid), 2015年5月20日。
(由Junio C Hamano -- gitster --合并于提交 324a9f4, 2015年6月1日)
协助者:Philip Oakley (PhilipOakley), Johannes Schindelin (dscho), Sebastian Schuberth (sschuberth), SZEDER Gábor (szeder)

现在,所有的配置都可以直接在Git中进行,使用 mergetools/winmerge

  • diff 命令:"$merge_tool_path" -u -e "$LOCAL" "$REMOTE"
  • merge 命令:"$merge_tool_path" -u -e -dl Local -dr Remote "$LOCAL" "$REMOTE" "$MERGED"

mergetools:添加winmerge作为内置工具

添加一个winmerge脚本,其中包含this thread中描述的命令,以便用户可以在不需要进行任何额外配置的情况下使用winmerge。


更新于2023年5月17日,我认为最好的命令行如下:

"C:/Program Files/WinMerge/winmergeu.exe" -e -u -am -wl -wr -fm -dl "Mine: $LOCAL" -dm "Merged: $BASE" -dr "Theirs: $REMOTE" "$LOCAL" "$BASE" "$REMOTE" -o "$MERGED"

请注意,使用了-am选项,这意味着“自动合并中间面板”。
"$LOCAL" "$BASE" "$REMOTE"表示显示三个面板,从左到右,共同的基础在中间面板显示,但WinMerge将自动合并它。
-o "$MERGED"表示当我们关闭WinMerge时,中间面板的内容将写入最终文件(您正在尝试解决冲突的文件)。

注意:ollydbg23评论中和{{link3:WinMerge/winmerge讨论1853}}中提出了一个问题:

合并后,如果最终文件仍存在冲突,WinMerge不会给出通知。

因此,提出了功���请求1855

3
这个帖子还提到了这个配置,它完全解决了我的问题。谢谢。 - faidherbard
@VonC,你知道如何让git显示新添加文件的差异吗?对于新添加的文件,WinMerge会显示一个带有\\.\nul的对话框,这是无效的路径。因此,WinMerge甚至不会显示差异。 - hIpPy
@ollydbg23 是的,但你可以考虑使用一个包装器将WinMerge配置为mergetool:请参见我的gist中的说明 - VonC
@ollydbg23 好的:我正在关注你在那个帖子中的讨论。当你想让我编辑我的回答并包含你的结论时,请告诉我。 - VonC
@ollydbg23 我已经完成了初步编辑:你能否编辑答案,包括你当前的WinMerge设置?我会审查并批准你的编辑。 - VonC
显示剩余11条评论

17

以下是我的配置文件(在Windows 7 Home Pro上为%userprofile%\.gitconfig,在*nix上为~/.gitconfig),没有包装:

[diff]
    tool = winmerge
[difftool "winmerge"]
    cmd = c:/path/to/winmergeu.exe -e -u -x -wl -wr -dl "base" -dr "mine" \"$LOCAL\" \"$REMOTE\"

我是一个完全的Git新手。那看起来像是一些配置文件(比如.ini文件)。你能说一下它在哪里吗? - aikeru
2
好的,我找到了 :) 这个文件显然是在 ~/.gitconfig 中,而在Windows中它似乎是我的用户文件夹,即:c:\users\myuserfolder\。 - aikeru
为什么你以只读方式打开文件?(-wl -wr)这肯定会破坏合并的目的吧? - BJury
3
在配置示例中,WinMerge被配置为“difftool”,用于只读查看差异。有关合并的详细信息,请参考@eis的答案。 - ellotheth
1
这是针对一个差异比较工具的。问题是在询问一个合并工具。 - Andrew Theken
我已经尝试过这个,但是Winmerge打开了一个“选择文件或文件夹”的对话框,左侧文件已经填好了,而右侧文件为空。 - Ed Randall

7

将WinMerge作为Visual Studio 2017 Git插件的比较和合并工具:

从Windows命令提示符中:输入命令 >> git config --global --edit,这将打开.getconfig文件进行编辑。

请使用以下命令进行更新:

[mergetool]
   prompt = false
   keepBackup = false
   keepTemporaries = false
[merge]
   tool = winmerge
   [mergetool "winmerge"]
   name = WinMerge
   trustExitCode = true
   cmd = \"C:\\Program Files (x86)\\WinMerge\\WinMergeU.exe\" -e -u -dl \"Base\" -dr \"Mine\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
[diff]
   tool = winmerge
   [difftool "winmerge"]
   name = WinMerge
   trustExitCode = true
   cmd = \"C:\\Program Files (x86)\\WinMerge\\WinMergeU.exe\" -u -e $LOCAL $REMOTE

7

我最初赞成@CapinWinky提出的使用SourceTree中的WinMerge答案。该答案仍然有效,但是WinMerge现在还支持三方合并,需要额外的参数。

在SourceTree选项对话框中,我选择了"自定义"作为合并工具,并输入以下命令:

C:\Program Files\WinMerge\WinMergeU.exe

并将参数设置为:

-u -fm -wl -wr -dl Remote_RO -dm Local_Merged -dr Base_RO $REMOTE $LOCAL $BASE -o $MERGED

现在似乎不必再将远程/本地/base参数用引号括起来,以适应其中包含空格的路径。

此配置是为了将中间窗格用作合并后的输出文件。

命令行参考

我曾经遇到这样的问题:尝试进行合并时,WinMerge无法打开。Sourcetree启动Git来打开你选择的工具。当使用Sourcetree的自定义选项时,你的git配置文件(例如C:\Users\Me\.gitconfig)会被修改以添加一个名为“sourcetree”的新合并工具,并且Git命令包括--tool=sourcetree。某个时刻.gitconfig文件没有被正确更新,我在该部分中有两个“cmd”行,其中一个被破坏了:

[mergetool "sourcetree"]
    cmd = 'C:/Program Files/WinMerge/WinMergeU.exe' -u -fm -wl -wr -dl Remote_RO -dm Local_Merged -dr Base_RO $REMOTE $LOCAL $BASE -o $MERGED
    trustExitCode = true
    cmd = 'C:/Program '

手动修复.gitconfig文件解决了该问题。

谢谢。这是唯一与Visual Studio 2019兼容的配置。 - Ramanpreet Singh

7
这是一种更容易实现的方法,也是我成功的方法:
git config --global diff.tool winmerge

git config --replace --global difftool.winmerge.cmd "\"C:\path to winmerge\WinMergeU.exe\" -e -u -dl \"Base\" -dr \"Mine\" $LOCAL $REMOTE"

git config --global difftool.prompt false

1
我认为在这个版本中$LOCAL和$REMOTE被交换了。 - Tom
1
Tom,不仅如此,而且在$REMOTE和$LOCAL变量之前的反斜杠会导致WinMerge出现问题(我现在使用的是最新版本2.14.0.0)。 - zumalifeguard
我省略了 -dl "Base",这样一侧显示文件名。另一侧仍然标记为“Mine”,以便清楚。 - GregHNZ

6

您的路径不正确,应该为"/c/Program Files (x86)/WinMerge/WinMergeU.exe"

您正在使用shell脚本环境,而不是本机Windows命令提示符。


5
安装 TortoiseGit 和 WinMerge 2.16(此版本支持三方合并)后,我发现 WinMerge 如何集成到 TortoiseGit 中:
D:\Program Files\WinMerge\WinMergeU.exe /e /ub /fm /wl /wr /dl %tname /dm %bname /dr %yname  %theirs %base %mine /o %merged /am

所以我编辑了.gitconfig文件,并更改了一些变量使其适用于我(我将WinMerge目录添加到系统路径中):

[mergetool "winmerge"]
    cmd = WinMergeU -e -ub -fm -wl -wr $LOCAL $BASE $REMOTE -o $MERGED -am

/ub 不是有效的标志。此外,我不确定您是否想要自动合并基础 (/am 标志)。我认为这没有太多意义。虽然我仍然不完全清楚 /ar /am /al 自动合并标志实际上是做什么的。 - BigDru

4

通过命令行进入设置已经被其他答案覆盖。对于使用WinMerge进行完整三向合并的.gitconfig文件可以像这样进行配置(此示例来自Windows):

[merge]
    tool = WinMerge

[mergetool "WinMerge"]
    cmd = \"C:\\Program Files\\WinMerge\\WinMergeU.exe\" -e -u -dl \"Local\" -dm \"Base\" -dr \"Remote\" \"$LOCAL\" \"$BASE\" \"$REMOTE\" -o \"$MERGED\"
    trustExitCode = true
    keepBackup = false

[diff]
    tool = WinMerge

[difftool "WinMerge"]
    cmd = \"C:\\Program Files\\WinMerge\\WinMergeU.exe\" -e -u -dl \"Old $BASE\" -dr \"New $BASE\" \"$LOCAL\" \"$REMOTE\"
    trustExitCode = true

标志信息:

  • /e - 允许通过按一次“esc”键关闭WinMerge。
  • /u - 防止WinMerge记录最近使用的文件列表中的文件。
  • /dl、/dm和/dl - 左、中和右面板的说明。
  • /o - 输出文件。保存任何一个面板将输出该面板的内容到输出文件。

trustExitCode = true告诉git接受输出而无需进一步提示。

keepBackup = false会自动删除自动生成的*.orig文件。

注意:使用difftool时,$BASE和$MERGE变量都只包含文件名。


非常感谢。我希望在阅读时更加注意/o标志的描述。这个回复为我解决了一切问题。 - BigDru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接