使用Git中的Winmerge来存档diff

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

2015年6月更新,6年后:

正如在“ git mergetool winmerge ”中详细描述的,一个简单的git config diff.tool winmerge就足够了。

Git 2.5+(Q2,2015)现在意识到Winmerge是一个差异或合并工具!


原始答复(2009-2012)

(msysgit,1.6.5,DOS会话)

第一部分(使用winmerge)在“ 如何用视觉差异程序查看'git diff'输出 ”中描述。

 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命令行选项 )

 git difftool 

现在将启动WinMerge。
如果你想git diff启动WinMerge,只需设置:

 set GIT_EXTERNAL_DIFF=winmerge.sh 

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

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

比较目录而不是逐个文件将很快可用:
见[ANNOUNCE] Git 1.7.11.rc1 :

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

请参阅“ 补丁difftool :教difftool来处理目录差异 ”和答案“ 目录比较的Git分支 ”的更多细节。


原文difftool by directories script(2009年12月)

正如Seba Illingworth在他的回答中提到的,脚本git-diffall.sh(也放在path中)可以做到这一点:

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

但是,这只能通过打开n个窗口的n个文件(如果您尝试使用WinMerge的-s选项,它不会工作,因为临时文件太早被difftool删除)


这就是为什么我喜欢GitDiff.bat的方法- 与GI进行权力差异 ,这使您可以在select一个文件来检查其内部差异之前,查看差异的文件列表。
我已经调整它只使用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将closures所有的WinMerge-diff会话。

我在2个地方使用第一部分遇到麻烦并且固定它如下

  1. 设置winmerge.cmd的第二个命令需要在cmdline上(在$ LOCAL和$ REMOTE之前)额外的斜线,否则cygwin将在cmdline中replace该variables

     C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"\$LOCAL\" \"\$REMOTE\"" 
  2. 更改winmerge.sh文件(没有这个,得到右path无效的错误)

     #!/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")" 

由于线程变得困惑和分叉,下面是用于msysgit Git Windows的目录列表“–dir-diff”WinMerge方法的整合指令。

步骤1 – 在path可访问的位置(如/home/bin/winmerge.sh)创build一个名为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中input以下命令来指示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中input以下命令来testing你的WinMerge diff:

 git difftool --dir-diff 

第4步 – 为了更快地访问,通过将此行添加到您的主文件夹中的.bashrc(或者如果文件尚不存在,则使用此行创build.bashrc文件),为此命令创build一个别名:

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

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

 diffdir 

我有一个脚本,它将在Gitconfiguration中设置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中

我很困惑为什么解决scheme是作为一个DOSbatch file呈现的,因为我的Git安装带有一个bash shell。 我也无法得到从bash运行的DOS上下文,所以我试图调整以前在bash上下文中共享的内容。

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

首先,将gitprepdiff.shconfiguration为前面提到的difftool

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

我还注意到, git configure命令的结果可以直接在C:\Users\<username>\.gitconfigurefind并编辑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 

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

在Windows上,你可以这样做:

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

2)添加下面的行。 注意包装winmergepath的单引号:

 [diff] tool = winmerge [difftool "winmerge"] cmd = "'C:/Program Files (x86)/WinMerge/WinMergeU.exe'" -e "$LOCAL" "$REMOTE" [difftool] prompt = false [merge] tool = winmerge [mergetool "winmerge"] cmd = "'C:/Program Files (x86)/WinMerge/WinMergeU.exe'" \"$MERGED\" \"$REMOTE\" [mergetool] keepBackup = false trustExitCode = false 
 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命令行手册 :“参数前面带有正斜杠(/)或短划线( – )字符”

没有configuration:

 git difftool --tool winmerge 

假设:

  • Winmerge已安装
  • Git for windows是从“git version 2.12.0.windows1”或更高版本安装的(尽pipe较早版本的git可能已经引入了该命令)。