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

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

有很多不同的程序可以用作你的git difftool和mergetool,并且对于哪个是最好的当然没有共识(意见、需求和操作系统显然会有所不同)。

Meld是一个流行的免费,开源,跨平台(UNIX/Linux, OSX, Windows)的选择,如StackOverflow问题,Git最好的可视化合并工具是什么?所示,其中提出Meld的答案的票数是其他任何工具的3倍多。

下面我将回答以下2个问题:

  • 我如何设置和使用Meld作为我的git difftool?
  • 我如何设置和使用Meld作为我的git合并工具?

注意:没有必要使用相同的程序作为你的difftool和mergetool,可以为两者设置不同的程序。

273590 次浏览

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

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

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

# 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

如果正确配置Meld窗口将打开显示差异使用GUI界面。

Meld GUI窗口窗格的顺序可以通过$LOCAL$REMOTEcmd中的顺序来控制,也就是说哪个文件显示在左边窗格中,哪个文件显示在右边窗格中。如果你想让它们反过来,只需像这样交换它们:

    cmd = meld "$REMOTE" "$LOCAL"

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


我如何设置和使用Meld作为我的git合并工具?

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

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

# 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以通常的方式执行一个合并。如。

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将包含包含合并冲突信息的部分合并文件(即包含所有>>>>>>><<<<<<<条目的文件)。

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

git mergetool

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

在上面的例子.gitconfig条目中,建议2行作为[mergetool "meld"] cmd行。事实上,高级用户有各种各样的方法来配置cmd行,但这超出了本回答的范围。

这个答案有2个可供选择的cmd行,它们之间,将迎合大多数用户,并将是一个好的起点,高级用户谁希望采取工具的下一个复杂水平。

首先是这些参数的含义:

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

我建议你使用其中一种:

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

或者:

[mergetool "meld"]
cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"
# See 'Note On Output File' which explains --output "$MERGED".

选择是在$LOCAL$REMOTE之间使用$MERGED还是$BASE

无论采用哪种方式,Meld都会显示3个窗格,其中$LOCAL$REMOTE位于左窗格和右窗格,$MERGED$BASE位于中间窗格。

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

关于输出文件的注意事项:不要担心--output "$MERGED"cmd中被使用,不管$MERGED$BASE是否在cmd行前面被使用。--output选项只是告诉Meld git希望将冲突解决文件保存在哪个文件名中。不管你是使用$MERGED还是$BASE作为开始编辑点,Meld都会将你的冲突编辑保存在那个文件中。

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

git会通过将.orig附加到原始文件名后,对部分合并的文件进行备份,其中包含合并冲突信息。例如file_name.orig。在检查您是否满意合并并运行您可能希望执行的任何测试之后,可以删除.orig文件。

此时,您现在可以执行一个提交操作来提交更改。

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

如果你有超过1个文件存在合并冲突,git会为每个文件打开一个新的合并窗口,一个接一个,直到它们全部完成。它们不会同时打开,但是当您完成其中一个冲突的编辑并关闭Meld时,git将打开下一个冲突,以此类推,直到所有的合并冲突都得到解决。

生活项目上使用git mergetool之前,创建一个虚拟项目来测试它的使用是明智的。确保在你的测试中使用一个包含空格的文件名,以防你的操作系统要求你转义cmd行中的引号,见下文。


转义引号字符

一些操作系统可能需要转义cmd中的引号。缺乏经验的用户应该记住,配置命令行应该使用包含空格的文件名进行测试,如果cmd行不能使用包含空格的文件名,则尝试转义引号。如。

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

在某些情况下,可能需要更复杂的引号转义。下面的第一个Windows路径链接包含了对每个引号进行三重转义的示例。这很无聊,但有时是必要的。如。

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

Windows路径

Windows用户可能需要在Meld cmd行中添加额外的配置。它们可能需要使用meldc的完整路径,该路径被设计为在Windows上从命令行调用,或者它们可能需要或想要使用包装器。他们应该阅读下面链接的StackOverflow页面,其中关于为Windows设置正确的Meld cmd行。由于我是一个Linux用户,我无法测试各种Windows cmd行,并且没有关于这个主题的进一步信息,除了建议使用我的例子,添加到Meld或meldc的完整路径,或将Meld程序文件夹添加到你的path

用Meld忽略尾随空格

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

在首选项Text Filters选项卡中,有几个有用的过滤器可以在执行diff时忽略注释之类的东西。尽管有过滤器可以忽略All whitespaceLeading whitespace,但没有忽略Trailing whitespace过滤器(这已被建议作为Meld邮件列表中的附加功能,但在我的版本中没有)。

忽略后面的空格通常是非常有用的,特别是在协作时,并且可以通过在Meld首选项Text Filters选项卡中使用简单的正则表达式轻松手动添加。

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

我希望这对每个人都有帮助。

虽然另一个答案是正确的,但下面是将Meld配置为可视化差异工具的最快方法。只需复制/粘贴这个:

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

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

边注:Meld出奇地慢用于比较CSV文件,我发现没有Linux diff工具比这个名为比较它!的Windows工具更快(上次更新于2010年)。

从$MERGED中的不同部分中计算一个差值并应用它可能很复杂。在我的设置中,meld通过可视化地显示这些差异来帮助你,使用:

[merge]
tool = mymeld
conflictstyle = diff3


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

它看起来很奇怪,但提供了一个非常方便的工作流程,使用三个标签:

  1. 在TAB 1中,你会看到(从左到右)你应该在TAB 2中做出的改变来解决合并冲突。

  2. 在TAB 2的右边,你应用&;change that you should make&;并将整个文件内容复制到剪贴板(使用ctrl-a和ctrl-c)。

  3. 在TAB 3替换右边的剪贴板内容。如果一切正确,您现在将从左到右看到与tab 1中显示的相同的更改(但上下文不同)。保存在此选项卡中所做的更改。

注:

  • 不要在TAB 1中编辑任何内容
  • 不要在TAB 2中保存任何东西,因为这会在TAB 3中产生烦人的弹出窗口

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

git config --global alias.meld '!git difftool -t meld --dir-diff'
这使得它类似于git-meld.pl脚本: https://github.com/wmanley/git-meld < / p >

然后你就可以跑了

git meld

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

git config --global diff.tool meld
git config --global difftool.meld.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文件路径不同,请更新。)

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

你可以使用下面的命令来验证Meld的路径:

which meld
这是一个主要针对使用Windows的开发人员的答案 diff工具的路径语法不同于其他平台。< / p >

我使用Kdiff3作为git的合并工具,但要设置git的difftool为Meld,我 首先从Meldmerge.org安装最新版本的Meld 然后添加以下到我的全局。gitconfig使用:

git config --global -e
注意,如果你想要Sublime Text 3而不是默认的Vim作为核心编辑器,你可以

[core]
editor = 'c:/Program Files/Sublime Text 3/sublime_text.exe'

然后添加inn Meld作为difftool

[diff]
tool = meld
guitool = meld


[difftool "meld"]
cmd = \"C:/Program Files (x86)/Meld/Meld.exe\" \"$LOCAL\" \"$REMOTE\" --label \"DIFF
(ORIGINAL MY)\"
prompt = false
path = C:\\Program Files (x86)\\Meld\\Meld.exe

注意上面cmd中的斜杠,在Windows上这是必要的。

也可以设置一个别名,用——dir-diff来显示当前的git差异 选择。这将列出在Meld中更改的文件,当您更改了多个文件时(确实是一个非常常见的场景),这很方便。< / p >

别名在.gitconfig文件中,在(别名)部分下面:

showchanges = difftool --dir-diff

为了显示我对代码所做的更改,我只需输入以下命令:

git showchanges
下图显示了——dir-diff选项如何显示已更改文件的列表(示例): Meld显示$LOCAL和$REMOTE之间变化的文件列表 < / p >

然后,可以单击每个文件并显示Meld内部的更改。

对于Windows 10,我必须把这个放在我的。gitconfig中:

[merge]
tool = meld
[mergetool "meld"]
cmd = 'C:/Program Files (x86)/Meld/Meld.exe' $LOCAL $BASE $REMOTE --output=$MERGED
[mergetool]
prompt = false

你需要知道的其他一切都写在这个了不起的回答由马特更远的上面。

PS:由于某些原因,这只适用于Meld 3.18。x,而一些Meld 3.20。X版本给我一个错误。它应该与TomasMolina在下面的评论中提到的Meld 3.20.4一起工作。

我使用meld遵循这个简单的设置。Meld是免费的开源差异工具。对于任何代码更改,您将看到文件和目录的比较。

  1. 使用yum/apt在Linux中安装meld。
  2. 在~/中添加以下行。gitconfig文件
[diff]
tool = meld
  1. 转到代码repo并输入以下命令查看上次提交的更改与当前工作目录之间的差异(未分阶段未提交的更改)

Git difftool——dir-diff ./

  1. 要查看上次提交的代码和阶段性代码之间的差异,请使用以下命令

Git difftool——cached——dir-diff ./

对于@mattst的精彩回答,除了这个没有什么可补充的。对于使用Windows Subsystem For Linux (WSL2)的人,可以在Linux中开发,但在Windows中使用Meld。

cmd = "/mnt/c/Program Files (x86)/Meld/Meld.exe" "$LOCAL" "$REMOTE"

注意:我的所有代码都在Windows驱动器上,而不是WLS2虚拟驱动器上,所以是YMMV。