如何使用 msysgit / gitk 设置 DiffMerge?

Posted

技术标签:

【中文标题】如何使用 msysgit / gitk 设置 DiffMerge?【英文标题】:How do I setup DiffMerge with msysgit / gitk? 【发布时间】:2010-10-21 07:02:55 【问题描述】:

我刚开始使用 Git,可能我错过了一些明显的东西,但这里是:

我在 Windows XP 上使用 msysgit 1.6.2.2 安装时,我选择了“仅使用 Git Bash”选项 1

我正在尝试组合一个包装脚本,我可以用它来用 DiffMerge 替换内置的 git diff。基于 SO 上的this thread,我创建了以下批处理文件:

@echo off
REM ---- Switch forward slashes to back slashes ----
set oldW=%2
set oldW=%oldW:/=\%
set newW=%5
set newW=%newW:/=\%

REM ---- Launch DiffMerge ----
"C:/Programs/SourceGear/DiffMerge/DiffMerge.exe" /title1="Old Version" %oldW% /title2="New Version" %newW%

我将 bat 文件放在 %GIT_INSTALL%/cmd 下,并按如下方式编辑了我的 .gitconfig 文件:

[diff]
external = C:/Programs/git/cmd/git-diff-wrapper.bat

如果我启动 Git Bash 并执行 git diff HEAD HEAD~ -- 我的文件

我收到一条消息 File (\dev\null) not found - 鉴于我在 Windows 上,这并不奇怪。

按下,我启动了 gitk,在 Edit>Preferences 下,我选择了相同的包装脚本。为特定文件尝试“外部差异”选项会给出神秘的错误消息Unknown Option "

显然,我不知道自己在做什么了,因此我们将不胜感激。

【问题讨论】:

刚刚按照要求用一些“DiffMerge”特定元素完成了我的回答。 【参考方案1】:

我刚刚经历了与setting Notepad++ as my external editor with msysgit1.6.2.2 有点相似的经历。

关键是要意识到包装器不是 DOS 脚本,而是 /bin/sh 脚本。

所以试着输入你的“.bat”(即使它不完全是一个 bat 脚本,扩展名在这里并不重要):

#!/bin/sh

# diff is called by git with 7 parameters:
# path old-file old-hex old-mode new-file new-hex new-mode

"C:/Programs/SourceGear/DiffMerge/DiffMerge.exe" /title1="Old Version" "$2" /title2="New Version" "$5" | cat

不用担心让所有的 '\' 变成 '/':这是由 Git 脚本调用外部 diff 工具完成的。

我没有使用 DiffMerge 对其进行测试,但使用 WinMerge,无论是从 DOS 会话还是 Git Shell 都可以正常工作。

#!/bin/sh
"C:/Program Files/WinMerge/WinMergeU.exe" -e -ub "$2" "$5" | cat

(使用 '-e' 选项,我只需输入 'ESC' 即可关闭并退出 diff 工具:效果很好!)


average_geek 在 cmets 中添加:

添加了“/bin/sh”标头并尝试再次运行 git diff。 这次的错误是:Unexpected parameter 'C:/Docume~/avggeek/LOCALS~1/Temp/.diff_b08444 有没有办法查看我调用git diff时传递的参数是什么?

1/ 实际上有一种方法可以查看传递的参数是什么! 在C:\Program Files\Git\libexec\git-core\git-sh-setup 文件中添加以下行:

git_editor() 
    : "$GIT_EDITOR:=$(git config core.editor)"
    : "$GIT_EDITOR:=$VISUAL:-$EDITOR"
    case "$GIT_EDITOR,$TERM" in
    ,dumb)
        echo >&2 "No editor specified in GIT_EDITOR, core.editor, VISUAL,"
        echo >&2 "or EDITOR. Tried to fall back to vi but terminal is dumb."
        echo >&2 "Please set one of these variables to an appropriate"
        echo >&2 "editor or run $0 with options that will not cause an"
        echo >&2 "editor to be invoked (e.g., -m or -F for git-commit)."
        exit 1
        ;;
    esac
#### ADD THIS LINE BELOW
    echo >&2 "editor is $GIT_EDITOR:=vi $@."
#### END ADDITION ABOVE
    eval "$GIT_EDITOR:=vi" '"$@"'

您将看到正在调用哪个编辑器,使用什么参数。

现在,关于“意外参数”部分: 当我用“/e /ub”而不是“-e -ub”调用 WinMergeU.exe 时,我确实遇到了同样的错误,所以第一个问题是: 您确定“/title1”位不能用作“-title1”或“-t1”或“--title1”或“--t1”吗?这就是Is可以从chapter 9 "Command Lines Arguments" of the pdf documentation of DiffMerge看到的。 如果不是,我怀疑一些双引号是为了正确分隔不同的参数。比如:

"/title1="Old Version"" "$2" "/title2="New Version"" "$5"
or
"/title1=\"Old Version\"" "$2" "/title2=\"New Version\"" "$5"

但我的钱宁愿放在“-title1”或“-t1”表格上:

-t1="Old Version" "$2" -t2="New Version" "$5"

应该可以正常工作。

【讨论】:

我添加了 /bin/sh 标头并尝试再次运行 git diff。这次的错误是:Unexpected parameter 'C:/Docume~/avggeek/LOCALS~1/Temp/.diff_b08444 Is there a way to see what are the parameters getting passed when I call git diff`? "关键是要意识到包装器不是 DOS 脚本,而是 /bin/sh 脚本。"对于像我这样没有激活“仅使用 Git Bash”选项的人,它必须是 Windows 脚本(.cmd 更时尚......)与您的相同,但使用 %2 而不是 $2【参考方案2】:

VonC - 切换到 -t1 和 -t2 修复了错误。 Diffmerge 现在适用于 git bash :)

在the gitk patch 添加了 External Diff 支持之后,我意识到它直接以两个文件作为参数调用了 External Diff 程序。于是我修改了 gitk>Edit>Preferences 并将以下命令直接放入 External Diff Tool 选项中:

"C:/Programs/SourceGear/DiffMerge/DiffMerge.exe" -t1="Old Version" -t2="New Version"

现在我也让 DiffMerge 为 gitk 工作了 :-)

【讨论】:

太棒了,它确实有效!感谢您对 gitk 的反馈。 +1 使用最新的 Diffmerge 路径更可能是“C:/Program Files/SourceGear/Common/DiffMerge/sgdm.exe”,并且 -t1/-t2 不再起作用。如果你把它放在一边,你至少会得到比较窗口【参考方案3】:

这对我有用,如下所示:

~/.gitconfig:

[merge]
tool = diffmerge
[mergetool "diffmerge"]
cmd = \"C:/Program Files/git/cmd/git-diffmerge-merge.sh\" \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
trustExitCode = false

C:\Program Files\Git\cmd\git-diffmerge-merge.sh:

#!/bin/sh

localPath="$2"
basePath="$1"
remotePath="$3"
resultPath="$4"

if [ ! -f $basePath ]
then
    basePath="~/diffmerge-empty"
fi

"C:/Program Files/SourceGear/DiffMerge/DiffMerge.exe" --merge --result="$resultPath" "$localPath" "$basePath" "$remotePath" --title1="Mine" --title2="Merged: $4" --title3="Theirs"

部分功劳归http://therightstuff.de/2009/01/28/Setting-Up-SourceGear-DiffMerge-With-Git.aspx ;)

【讨论】:

谢谢。你用这个救了我。【参考方案4】:

我在整个互联网上寻找答案。我尝试了上面和其他地方的所有解决方案。我可以让合并部分工作,而不是 diff 部分,反之亦然。所以我最终所做的就是从我在互联网上获得的所有适合我的信息中破解我自己的简单解决方案。 它不需要任何脚本,只需编辑您的.gitconfig,它通常位于以下目录C:\Documents and Settings\[username] 您需要已经安装了 DiffMerge 程序。

这是我的.gitconfig 文件的相关摘录。您只需要编辑您的DiffMerge 版本所在的路径。 注意我在路径中使用了旧的 DOS 8.3 格式

[diff]
    tool = diffm
[difftool "diffm"]
    cmd = "H:/PROGRA~1/SourceGear/DiffMerge/DiffMerge.exe $LOCAL $REMOTE"
    prompt = false

[merge]
    tool = diffmerge
[mergetool "diffmerge"]
    cmd = "H:/PROGRA~1/SourceGear/DiffMerge/DiffMerge.exe --merge --result=$MERGED $LOCAL $BASE $REMOTE" 
    trustExitCode = false
    keepBackup = false

如果您愿意,也可以使用命令git config --replace --global [options] 进行设置。


这个简单的解决方案也非常适合我。对于较新版本的 DiffMerge (3.3.1),需要更改命令路径:

    cmd = "C:/PROGRA~1/SourceGear/Common/DiffMerge/sgdm.exe ...etc..."

【讨论】:

支持一个有意义的简单解决方案。 就像@Bnjmn 说的,+1 用于只需要编辑 .gitconfig 的简单解决方案 我的关键是将... /merge /replace=... 更改为... --merge --replace=...; SourceGear's docs 好像错了。

以上是关于如何使用 msysgit / gitk 设置 DiffMerge?的主要内容,如果未能解决你的问题,请参考以下文章

TortoiseGit配合msysGit在Git@OSC代码托管的傻瓜教程

如何在 msys2 中使用 gitk?

gitk更改主题设置打不开

如何找到hg的gitk工具类型

gitk中文乱码问题处理

码农日常生活之Git & Gitlab & Gitk