乌龟合并工具能否在Windows Git Bash中作为差异工具使用?

52

我刚开始使用Git。 我想使用TortoiseMerge作为difftool和mergetool。

在我的$HOME/.gitconfig文件中,我有以下几个部分。 为了这个问题,我已经删除了用户和颜色部分。

[merge]
    tool = tortoisemerge
[mergetool "tortoisemerge"]
    cmd = \"TortoiseMerge.exe\" -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"
[diff]
    tool = tortoisemerge
[difftool "tortoisemerge"]
    cmd = \"TortoiseMerge.exe\" -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"
如果我在 Git Bash 提示符下键入 tortoisemerge,它会被加载。已知该命令位于路径上。但是如果我键入该命令,我会收到以下错误信息。

如果我在 Git Bash 提示符下键入 tortoisemerge,它会被加载。已知该命令位于路径上。但是如果我键入该命令,我会收到以下错误信息。

Rich:mygittest (master *)
$ git difftool
error: 'tortoisemerge' can only be used to resolve merges
merge tool candidates: kompare emerge vimdiff
No known merge resolution program available.
external diff died, stopping at readme.txt.
Rich:mygittest (master *)
$ 
我需要理解哪些内容才能使它正常工作? Tortoisemerge已与TortoiseSVN安装在一起。
7个回答

73

以下设置对我来说很好用。不过,我使用的是TortoiseGit而不是TortoiseSVN。请注意diff参数的差异。

[diff]
  tool = tortoisediff
[difftool]
  prompt = false
[merge]
  tool = tortoisemerge
[mergetool]
  prompt = false
  keepBackup = false
[difftool "tortoisediff"]
  cmd = \""c:/Program Files/TortoiseGIT/bin/TortoiseGitMerge.exe"\" -mine "$REMOTE" -base "$LOCAL"
[mergetool "tortoisemerge"]
  cmd = \""c:/Program Files/TortoiseGIT/bin/TortoiseGitMerge.exe"\" -base "$BASE" -theirs "$REMOTE" -mine "$LOCAL" -merged "$MERGED"

2
TortoiseMerge在处理Git混淆参数的方式上存在问题。因为TortoiseMerge使用冒号来分隔参数名和值,当处理带有空格的文件名时,Git会在两者周围加上引号。而TortoiseGitMerge允许使用空格并解决了这个问题。 - Rich Shealer
是msys bash搞乱了引号。显然,它应该与tortoise git 1.8一起使用。 - jwg
Perforce也无法处理冒号。我们应该要求TortoiseMerge添加替代语法。 - Colonel Panic
当我使用拥有TortoiseMerge.exeTortoiseSVN时,它对我有效。是的,使用TortoiseMerge.exe进行diff,而不是TortoiseIDiff.exegit difftool调用了TortoiseMerge GUI,非常方便!TortoiseMerge是最好的! - WesternGun

7
为了正确处理带有空格的文件名,您应该将@melbourn答案的最后一行更改为:
cmd = \""c:/Program Files/TortoiseGIT/bin/TortoiseGitMerge.exe"\" -base "$BASE" -theirs "$REMOTE" -mine "$LOCAL" -merged "$MERGED"

1
有什么区别吗?只是参数中的冒号被空格替换了吗?difftool是否应该进行类似的更改?我不知道是否值得编辑原始答案,或者是否有一些原因需要保留冒号。 - mwfearnley
1
冒号将被替换为空格。参数处理代码可以接受冒号或空格。但是,如果其中带有空格的文件名周围的引号不在“单词”的开头或结尾,则无法正确处理引号。 - jwg
3
@jwg,我现在已经修改了我的回答,考虑到了你的建议。谢谢! - Klas Mellbourn

2
这是更简单的方法,只需在git bash中运行以下命令:
git config --global merge.tool tortoisemerge

git config --global diff.tool tortoisediff
git config --global difftool.tortoisediff.cmd "TortoiseGitMerge \$LOCAL \$REMOTE"

我已经完成了。

----更多阅读----

您可能需要其他设置:

# you may want to disable prompt or merge backup
git config --global mergetool.keepBackup false
git config --global difftool.prompt false
git config --global mergetool.prompt false

# set the path only when it's not found in system path
git config --global mergetool.tortoisemerge.path "C:\Program Files\TortoiseGit\bin\TortoiseGitMerge.exe" 
git config --global difftool.tortoisdiff.path "C:\Program Files\TortoiseGit\bin\TortoiseGitMerge.exe"

要设置合并工具,你只需要设置正确的合并工具名称即可。它是官方支持的。

Git for Windows安装程序包括运行tortoisegitmerge作为合并工具的shell文件。它位于C:\Program Files\Git\mingw64\libexec\git-core\mergetools。(Git为合并提供4个变量:$BASE $LOCAL $REMOTE $MERGED,你可以在shell文件中查看它们。)

你可以使用命令检查你机器上所有支持的合并/比较工具:

git difftool --tool-help
git mergetool --tool-help

由于git diff工具不支持tortoisegitmerge,可能是因为此工具不支持目录比较(git difftool -d),所以您需要配置difftool命令以将其用作git difftool。

tortoisegitmerge工具有一个手册:
https://tortoisegit.org/docs/tortoisegitmerge/tme-automation.html
您可以找到最简单的文件差异方式:
TortoiseGitMerge BaseFilePath MyFilePath [ TheirFilePath ].
因此,我使用这种方法作为git difftool的命令。


0
[diff]
  tool = tortoisediff
[difftool]
  prompt = false
[merge]
  tool = tortoisemerge
[mergetool]
  prompt = false
  keepBackup = false
[difftool "tortoisediff"]
  cmd = \""C:/Users/$USER/Desktop/TortoiseMerge.exe"\" -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"
[mergetool "tortoisemerge"]
  cmd = \""C:/Users/$USER/Desktop/TortoiseMerge.exe"\" -base:\"$BASE\" -mine:\"$LOCAL\" -theirs:\"$REMOTE\" -merged:\"$MERGED\"

这对我有用,使用TortoiseMerge 1.6.7(便携版)


0

当进行变基操作时,我强烈建议交换$theirs$mine,因为在合并和变基合并时它们是不同的。在这里查看:

Git中"ours"和"theirs"的确切含义是什么?

所以,如果你像我一样只使用mergetool进行变基,请执行以下操作:

[mergetool "tortoisemerge"]
cmd = \""c:/Program Files/TortoiseGIT/bin/TortoiseGitMerge.exe"\" -base "$BASE" -theirs "$LOCAL" -mine "$REMOTE" -merged "$MERGED"

0

在Windows中使用TortoiseMerge需要先安装TortoiseSVN:

[guitool "VisualDiff"]
    cmd = git difftool -y \"$FILENAME\"
    needsfile = yes
    noconsole = yes
[diff]
    tool = tortoisediff
[difftool]
    prompt = false
[merge]
    tool = tortoisemerge
[mergetool]
    prompt = false
    keepBackup = false
[difftool "tortoisediff"]
    cmd = \""W:/Programs/TortoiseSVN/bin/TortoiseMerge.exe"\" "/mine:$REMOTE" "/base:$LOCAL"
[mergetool "tortoisemerge"]
    cmd = \""W:/Programs/TortoiseSVN/bin/TortoiseMerge.exe"\" "/base:$BASE" "/theirs:$REMOTE" "/mine:$LOCAL" "/merged:$MERGED"

0

Klas Mellbourn的回答非常好!省了我很多时间。 其中一个缺点是,仓库中新添加或删除的文件在执行difftool命令时不会显示出来。因为没有可比较的对象!以下是我在此基础上所做的: (受到我的同事answer的启发)。

  1. $Home目录下创建一个名为empty.empty的文件(在bash中执行start ~)。正如其名称所示,保持为空。
  2. $Home/bin目录下创建另一个名为tortoisediff.sh的文件,并添加以下内容:

:

#!/bin/sh
# $LOCAL $REMOTE seem to be swapped
# $1 is $LOCAL
# $2 is $REMOTE

difftool='/c/Program Files/TortoiseGit/bin/TortoiseGitMerge.exe'
NULL="/dev/null"
empty="C:/home/empty.empty"

if [ "$1" == "$NULL" ]; then
    echo "Added: " "$2"
    "$difftool" /base:"$empty" /mine:"$2" /readonly:"$empty"
elif [ "$2" == "$NULL" ]; then
    echo 'Removed: ' "$1"
    "$difftool" /base:"$1" /readonly:"$1" /mine:"$empty"
else
    echo 'Modified' "$2"
    "$difftool" /base:"$1" /basename:"$1" /readonly:"$1" /mine:"$2" /minename:"$2"
fi

# Checkout https://tortoisegit.org/docs/tortoisegitmerge/tme-automation.html for more
  1. 修改你的 .gitconfig 文件(答案的第11行)

    cmd = tortoisediff.sh "$LOCAL" "$REMOTE"

这将使 difftool 引用 tortoisediff.sh 而不是直接打开应用程序。

  1. 请注意:您需要运行 git add .,然后运行 git difftool --staged,而不是简单地运行 git difftool

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