设置和使用Meld作为你的git difftool和mergetool

虽然这个问题和答案中的大部分信息都在StackOverflow上可用,但它分布在很多页面上,以及其他答案都是错误的或误导的。 我花了一段时间来拼凑一切我想知道的东西。

有很多不同的程序可以用作你的git difftool和mergetool,当然哪个最好 (意见,要求和操作系统明显不同)没有共识。

Meld是一个stream行的跨平台(UNIX / Linux,OSX,Windows)的select,如StackOverflow问题所示, 什么是最好的Git视觉合并工具? 其中提出Meld的答案比其他任何工具都多3倍。

以下两个问题将在我的回答中得到解答:

  • 我如何设置和使用Meld作为我的git difftool?
  • 我如何设置和使用Meld作为我的git mergetool?

注意:不需要同时使用difftool和mergetool程序,可以同时设置不同的程序。

我如何设置和使用Meld作为我的git difftool?

git difftool使用GUI diff程序(即Meld)显示diff,而不是在terminal中显示diff输出。

尽pipe可以使用-t <tool> / --tool=<tool>在命令行上设置GUI程序,但在.gitconfig文件中configuration它更有意义。 [注意:请参阅关于转义引号和Windowspath的部分。]

 # Add the following to your .gitconfig file. [diff] tool = meld [difftool] prompt = false [difftool "meld"] cmd = meld "$LOCAL" "$REMOTE" 

[注:这些设置不会改变git diff的行为,它将继续照常运行。]

您使用git difftool的方式与您使用git diff完全相同。 例如

 git difftool <COMMIT_HASH> file_name git difftool <BRANCH_NAME> file_name git difftool <COMMIT_HASH_1> <COMMIT_HASH_2> file_name 

如果configuration正确,Meld窗口将会打开,使用GUI界面显示diff。

Meld GUI窗口窗格的顺序可以通过$LOCAL$REMOTE cmd命令来控制,也就是说哪个文件显示在左窗格中,哪个文件显示在右窗格中。 如果你想让他们换个方式,就像这样:

  cmd = meld "$REMOTE" "$LOCAL" 

最后, prompt = false行会阻止git提示你是否要启动Meld,默认情况下git会发出提示。


我如何设置和使用Meld作为我的git mergetool?

git mergetool允许您使用GUI合并程序(即Meld)来解决合并期间发生的合并冲突。

像difftool一样,你可以使用-t <tool> / --tool=<tool>在命令行上设置GUI程序,但是和以前一样,在你的.gitconfig文件中configuration它会更有意义。 [注意:请参阅关于转义引号和Windowspath的部分。]

 # Add the following to your .gitconfig file. [merge] tool = meld [mergetool "meld"] # Choose one of these 2 lines (not both!) explained below. cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED" cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED" 

你不使用git mergetool来执行实际的合并。 在使用git mergetool之前,你用git mergetool以通常的方式执行合并。 例如

 git checkout master git merge branch_name 

如果存在合并冲突,git将显示如下所示的内容:

 $ git merge branch_name Auto-merging file_name CONFLICT (content): Merge conflict in file_name Automatic merge failed; fix conflicts and then commit the result. 

此时file_name将包含带合并冲突信息的部分合并文件(即包含所有>>>>>>><<<<<<<条目的文件)。

Mergetool现在可以用来解决合并冲突。 你可以很容易地开始:

 git mergetool 

如果configuration正确,Meld窗口将打开显示3个文件。 每个文件都将包含在其GUI界面的单独窗格中。

在上面的示例.gitconfig条目中,build议使用两行作为[mergetool "meld"] cmd行。 事实上,高级用户可以通过各种方式来configurationcmd行,但这超出了本答案的范围。

这个答案有两个替代的cmd行,在它们之间可以满足大多数用户的需求,对于那些希望把工具带到下一个复杂程度的高级用户来说,这是一个很好的起点。

首先这里是什么参数的意思是:

  • $LOCAL是当前分支中的文件(例如master)。
  • $REMOTE是合并分支中的文件(例如branch_name)。
  • $MERGED是合并冲突信息的部分合并文件。
  • $BASE$LOCAL$REMOTE的共享提交祖先,这就是说,当包含$REMOTE的分支最初被创build时,它就是这个文件。

我build议你使用:

 [mergetool "meld"] cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED" 

要么:

 [mergetool "meld"] cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED" 

可以select是在$LOCAL$REMOTE之间使用$MERGED还是$BASE

无论哪种方式,Meld将在左侧和右侧窗格中显示3个窗格,使用$LOCAL$REMOTE ,在中间窗格中使用$MERGED$BASE

在这两种情况下,中间窗格是您应该编辑以解决合并冲突的文件。 不同之处在于你喜欢的开始编辑位置; $MERGED用于包含带有合并冲突信息的部分合并文件的文件或用于$LOCAL$REMOTE的共享提交祖先的$LOCAL $BASE 。 [由于这两个cmd行可以很有用,我把它们都保存在我的.gitconfig文件中。 大多数时候我使用$MERGED行, $BASE行被注释掉了,但是如果我想使用$BASE行,注释掉可以被交换。

编辑中间窗格以解决合并冲突后,只需保存该文件并closuresMeld窗口即可。 Git会自动执行更新,当前分支(例如master)中的文件现在将包含您在中间窗格中结束的任何内容。

git将通过将.orig添加到原始文件名中,对部分合并的文件和其中的合并冲突信息进行备份。 例如file_name.orig 。 在检查你对合并和运行任何你可能希望做的testing感到高兴之后, .orig文件可以被删除。

在这一点上,你现在可以做一个承诺提交更改。

注意:不要担心--output "$MERGED"cmd被使用,不pipe在cmd中是否早先使用了$MERGED$BASE--output选项只是告诉Meld git需要保存冲突解决文件的文件名。Meld将确保你的冲突编辑保存在那个文件中,无论你使用$MERGED还是$BASE作为你的开始编辑点。

如果在编辑Meld中的合并冲突时,希望放弃使用Meld,则退出Meld而不将合并parsing文件保存在中间窗格中。 git将回应与消息file_name seems unchanged ,然后问Was the merge successful? [y/n] Was the merge successful? [y/n] ,如果你回答n那么合并冲突解决将被中止,文件将保持不变。 请注意,如果您已经将文件保存在Meld中,那么您将不会收到来自git的警告和提示。 [当然,你可以删除这个文件,把它replace成git为你制作的备份.orig文件。]

如果你有多个合并冲突的文件,那么git会为每个文件打开一个新的Meld窗口,直到全部完成。 他们不会同时被打开,但是当你完成一个冲突的编辑,closuresMeld时,git会打开下一个,依此类推,直到所有的合并冲突得到解决。

实际项目中使用git mergetool之前,build立一个虚拟项目来testinggit mergetool的使用是明智的。 请务必尝试一个带有空格的文件,以防您的操作系统要求您在cmd行中转义引号,如下所示。


转义字符

某些操作系统可能需要将cmd的引号转义。 没有经验的用户应该记住,应该使用包含空格的文件名来testingconfiguration命令行,如果cmd行不能与包含空格的文件名一起使用,那么尝试转义引号。 例如

 cmd = meld \"$LOCAL\" \"$REMOTE\" 

在某些情况下,可能需要更复杂的引号转义。 下面的第一个Windowspath链接包含三个转义每个报价的示例。 这是一个缺点,但有时是必要的。 例如

 cmd = meld \\\"$LOCAL\\\" \\\"$REMOTE\\\" 

Windowspath

Windows用户可能需要额外的configuration添加到Meld cmd行。 他们可能需要使用meldc的完整path,这是从命令行在Windows上调用,或者他们可能需要或想要使用包装。 他们应该阅读下面链接的StackOverflow页面,这些页面是关于为Windows设置正确的Meld cmd行的。 因为我是一个Linux用户,所以我无法testing各种Windows cmd行,并且除了build议使用我的示例以外添加到Meld或meldc的完整path,或者将Meld程序文件夹添加到你的path

  • 在Windows上的Git Diff和Meld
  • 如何将Meld设置为git mergetool
  • Git mergetool与Meld在Windows上

忽略Meld的尾随空白

Meld有许多可以在GUI中configuration的首选项。

在“ Text Filters选项卡的首选项中,有几个有用的filter可以在执行差异时忽略注释等内容。 虽然有filter可以忽略All whitespaceLeading whitespace ,但是不会有忽略Trailing whitespacefilter(这在Meld邮件列表中被build议添加,但在我的版本中不可用)。

忽略尾随空白通常非常有用,特别是在协作时,可以使用Meld首选项“ Text Filters选项卡中的简单Python正则expression式轻松手动添加。

 # Use either of these regexes depending on how comprehensive you want it to be. [ \t]*$ [ \t\r\f\v]*$ 

我希望这有助于每个人。

而另一个答案是正确的,这里是最快捷的方式来configurationMeld作为你的视觉差异工具。 只需复制/粘贴这个:

 git config --global diff.tool meld git config --global difftool.prompt false 

现在在一个目录中运行git difftool ,Meld将为每个不同的文件启动。

注意:在比较CSV文件时, Meld的速度非常慢 ,而且我发现没有Linux差异工具比2009年时代的Windows工具“CompareIt!”更快。

对于Windows 。 在Git Bash中运行这些命令:

 git config --global diff.tool meld git config --global difftool.diff.path "C:\Program Files (x86)\Meld\Meld.exe" git config --global difftool.prompt false git config --global merge.tool meld git config --global mergetool.meld.path "C:\Program Files (x86)\Meld\Meld.exe" git config --global mergetool.prompt false 

(如果您的不同,请更新Meld.exe的文件path。)

对于Linux 。 在Git Bash中运行这些命令:

 git config --global diff.tool meld git config --global difftool.meld.path "/usr/bin/meld" git config --global difftool.prompt false git config --global merge.tool meld git config --global mergetool.meld.path "/usr/bin/meld" git config --global mergetool.prompt false 

您可以使用以下命令validationMeld的path:

 which meld 

我更喜欢将meld设置为单独的命令,如下所示:

 git config --global alias.meld '!git difftool -t meld --dir-diff' 

这使得它类似于这里的git-meld.pl脚本: https : //github.com/wmanley/git-meld

然后你可以运行

 git meld 

从$ MERGED的不同部分计算头部差异可能很复杂,并应用它。 在我的设置中,融合有助于通过视觉显示这些差异,使用:

 [merge] tool = mymeld conflictstyle = diff3 [mergetool "mymeld"] cmd = meld --diff $BASE $REMOTE --diff $REMOTE $LOCAL --diff $LOCAL $MERGED 

它看起来很奇怪,但提供了一个非常方便的工作stream程,使用三个选项卡:

  1. 在选项卡1中,您可以看到(从左到右)在选项卡2中应该进行的更改以解决合并冲突。

  2. 在选项卡2的右侧,应用“您应该进行的更改”并将整个文件内容复制到剪贴板(使用ctrl-a和ctrl-c)。

  3. 在标签3中将右侧replace为剪贴板内容。 如果一切都正确,现在您将从左到右看到与标签1中所示相同的更改(但具有不同的上下文)。 保存在此选项卡中所做的更改。

笔记:

  • 不要在标签1中编辑任何东西
  • 不要在标签2中保存任何内容,因为这会在标签3中产生恼人的popup窗口