在Git中使用Winmerge来编写diff

时间:2009-12-10 15:08:13

标签: git diff msysgit winmerge

有没有办法在git中使用Winmerge来做Diffs?

9 个答案:

答案 0 :(得分:112)

2015年6月更新,6年后:

详见“git mergetool winmerge”,简单的git config diff.tool winmerge即可。

Git 2.5+(2015年第2季度)现在已经知道Winmerge是差异化合并工具!


原始答案(2009-2012)

(msysgit,1.6.5,DOS会话)

第一部分(使用winmerge)在“How do I view ‘git diff’ output with visual diff program?

中描述
C:\myGitRepo>git config --replace --global diff.tool winmerge
C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
C:\myGitRepo>git config --replace --global difftool.prompt false

winmerge.sh存储在PATH的目录部分中:

#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"$PROGRAMFILES/WinMerge/WinMergeU.exe" -e -u -dl "Local" -dr "Remote" "$1" "$2"

(见WinMerge Command-line options

git difftool

现在将启动WinMerge 如果您希望git diff启动WinMerge,只需设置:

set GIT_EXTERNAL_DIFF=winmerge.sh

但真正的附加价值来自于能够使用相同的差异工具显示一个批次中的所有差异而不是按顺序呈现它们,迫使您关闭差异工具窗口一个文件时间。

2012年6月更新(2年半后):

即将比较目录而不是逐个文件:
[ANNOUNCE] Git 1.7.11.rc1

  

git difftool”学会了“--dir-diff”选项,可以在填充两个临时目录之后生成外部差异工具,这些工具可以一次比较两个目录层次结构 而不是每个文件对运行一次外部工具实例

有关详细信息,请参阅“ Patch difftool: teach difftool to handle directory diffs ”和答案“Directory comparison of Git branches”。


目录脚本原始difftool(2009年12月)

Seba Illingworth中提及his answer,脚本git-diffall.sh(也放在路径中)可以做到这一点:

#!/bin/sh
git diff --name-only "$@" | while read filename; do
    git difftool "$@" --no-prompt "$filename" &
done

但这仅适用于为 n 文件打开 n 窗口(如果您尝试使用WinMerge的-s选项,它将无法正常工作,因为过早地被difftool删除的临时文件)


这就是为什么我喜欢GitDiff.bat - power-diffing with GI的方法,它允许您在选择一个文件以查看其内部差异之前查看具有差异的文件列表。
我已将其调整为仅使用DOS命令

@echo off

setlocal

if "%1" == "-?" (
    echo GitDiff - enables diffing of file lists, instead of having to serially
    echo diff files without being able to go back to a previous file.
    echo Command-line options are passed through to git diff.
    echo If GIT_FOLDER_DIFF is set, it is used to diff the file lists. Default is windff.
    goto END
)

if "%GIT_DIFF_COPY_FILES%"=="" (
    rd /s /q %TEMP%\GitDiff
    mkdir %TEMP%\GitDiff
    mkdir %TEMP%\GitDiff\old
    mkdir %TEMP%\GitDiff\new

    REM This batch file will be called by git diff. This env var indicates whether it is
    REM being called directly, or inside git diff
    set GIT_DIFF_COPY_FILES=1

    set GIT_DIFF_OLD_FILES=%TEMP%\GitDiff\old
    set GIT_DIFF_NEW_FILES=%TEMP%\GitDiff\new

    set GIT_EXTERNAL_DIFF=%~dp0\GitDiff.bat
    echo Please wait and press q when you see "(END)" printed in reverse color...
    call git diff %*

    if defined GIT_FOLDER_DIFF (
        REM This command using GIT_FOLDER_DIFF just does not work for some reason.
        %GIT_FOLDER_DIFF% %TEMP%\GitDiff\old %TEMP%\GitDiff\new
        goto END
    )

    if exist "%ProgramFiles%\Beyond Compare 2\BC2.exe" (
        set GIT_FOLDER_DIFF="%ProgramFiles%\Beyond Compare 2\BC2.exe"
        "%ProgramFiles%\Beyond Compare 2\BC2.exe" %TEMP%\GitDiff\old %TEMP%\GitDiff\new
        goto END
    )

    "%ProgramFiles(x86)%\WinMerge\WinMergeU.exe" -r -e -dl "Local" -dr "Remote"  %TEMP%\GitDiff\old %TEMP%\GitDiff\new
    goto END
)

REM diff is called by git with 7 parameters:
REM     path old-file old-hex old-mode new-file new-hex new-mode
copy %TEMP%\%~nx2 %GIT_DIFF_OLD_FILES%\%1
copy %5 %GIT_DIFF_NEW_FILES%

:END

它不够强大,无法在不同目录中处理具有相同名称的文件,但它可以让您大致了解可能的内容:
这里只打开一个WinMerge,文件列表有内部差异。您可以单击要检查的那些,然后一个简单的 ESC 将关闭所有WinMerge-diff会话。

答案 1 :(得分:19)

我在2个地方使用第一部分遇到了麻烦,并将其修复如下

  1. 设置winmerge.cmd的第二个命令需要在cmdline上添加一个额外的斜杠(在$ LOCAL和$ REMOTE之前),否则cygwin将替换cmdline中的变量

    C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"\$LOCAL\" \"\$REMOTE\""
    
  2. 将winmerge.sh文件更改为(没有这个,导致路径无效错误)

    #!/bin/sh
    echo Launching WinMergeU.exe: "$(cygpath -aw "$1")" "$(cygpath -aw "$2")"
    "$PROGRAMFILES/WinMerge/WinMergeU.exe" -e -ub -dl "Base" -dr "Mine" "$(cygpath -aw "$1")" "$(cygpath -aw "$2")"
    

答案 2 :(得分:6)

由于线程变得混乱和分叉,这里是针对msysgit Git Windows的目录列表“--dir-diff”WinMerge方法的合并说明。

步骤1 - 在您的路径可访问的位置(例如/home/bin/winmerge.sh)创建一个名为winmerge.sh的文件,其中包含以下内容。

#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"$PROGRAMFILES/WinMerge/WinMergeU.exe" -r -ub -dl "Remote" -dr "Local" "$1" "$2"

第2步 - 在Git Bash中输入以下命令,指示git将winmerge.sh用作difftool(这些选项存储在/home/.gitconfig中):

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

第3步 - 现在您可以通过在Git Bash中键入以下命令来测试以启动WinMerge差异:

git difftool --dir-diff

步骤4 - 为了更快地访问,请通过在主文件夹中将此行添加到.bashrc来创建此命令的别名(如果文件尚不存在,则使用此行创建.bashrc文件) :

alias diffdir='git difftool --dir-diff'

第5步 - 现在只需在Git Bash中键入以下命令,即可快速查看WinMerge中的差异

diffdir

答案 3 :(得分:6)

我有一个脚本,它将在Git配置中设置Diff和Merge工具,并使用不需要单独的.sh文件的适当参数。它对我来说似乎很好。

git config --global diff.tool winmerge
git config --global difftool.prompt false
git config --global difftool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\""

git config --global merge.tool winmerge
git config --global mergetool.prompt false
git config --global mergetool.winmerge.trustExitCode true
git config --global mergetool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\""

注意 - 引用整个.cmd部分,以便参数将正确列在.gitconfig中

答案 4 :(得分:2)

我很困惑为什么解决方案是作为DOS批处理文件呈现的,因为我的Git安装附带了一个bash shell。我也无法从bash运行DOS上下文,所以我试图调整先前在bash上下文中共享的内容。

由于git diff似乎为每个文件运行一次指定的命令,我将我的解决方案拆分为两个bash脚本:

首先,将gitprepdiff.sh配置为如前所述的difftool

#!/bin/sh
#echo ...gitprepdiff.sh
cp -v $1 "$TMP/GitDiff/old/$2"
cp -v $2 "$TMP/GitDiff/new"

我还注意到可以在git configure

中直接找到并编辑C:\Users\<username>\.gitconfigure命令的结果

gitdiff.sh然后在命令行运行,您通常会调用git diff

#!/bin/sh
#echo Running gitdiff.sh...

DIFFTEMP=$TMP/GitDiff

echo Deleting and re-creating $DIFFTEMP...
rm -rf $DIFFTEMP;
mkdir $DIFFTEMP;

echo Creating $DIFFTEMP/old...
mkdir $DIFFTEMP/old;

echo Creating $DIFFTEMP/new...
mkdir $DIFFTEMP/new;

git diff --name-only "$@" | while read filename; do
    git difftool "$@" --no-prompt "$filename";
done

"$PROGRAMFILES\WinMerge\WinMergeU.exe" -r -e -dl "Repository" -dr "Working" $LOCALAPPDATA\\Temp\\1\\GitDiff\\old $LOCALAPPDATA\\Temp\\1\\GitDiff\\new

另外值得注意的是,在我的安装中,/tmp(在bash中)映射到%LOCALAPPDATA%\Temp\1\(在Windows中),这就是我在调用WinMerge时使用后者的原因。< / p>

答案 5 :(得分:2)

在Windows上你可以这样做:

1)打开.gitconfig文件。它位于您的主目录:c:\ users \ username.gitconfig

2)添加以下行。注意包裹winmerge路径的单引号:

==

答案 6 :(得分:2)

没有配置:

git difftool --tool winmerge

假设:

  • 安装了Winmerge
  • 从“git版本2.12.0.windows1”或更高版本安装了Git for windows(虽然早期版本的git可能已经引入了命令)。

答案 7 :(得分:1)

git config --global diff.tool winmerge
git config --global difftool.winmerge.cmd "\"$PROGRAMFILES\\WinMerge\\WinMergeU.exe\" -u -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\""
git config --global difftool.prompt false

根据WinMerge command line manual:“参数前缀为正斜杠(/)或短划线( - )字符”

答案 8 :(得分:0)

我可以在这里看到很多冗长且令人困惑的答案,因此在 2021 年在 windows10 上发布对我有用的简化和最小版本

 git config diff.tool winmerge
 git config --replace --global difftool.prompt false