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

时间:2015-12-06 16:35:04

标签: git meld

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

有许多不同的程序可以用作你的git difftool和mergetool,并且肯定没有就最好的(意见,要求和操作系统明显不同)达成共识)。

Meld是一个流行的跨平台(UNIX / Linux,OSX,Windows)选项,如 StackOverflow 问题What's the best visual merge tool for Git?中所示,其中提出Meld的答案超过3将投票时间视为任何其他工具。

以下2个问题将在下面的答案中回答:

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

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

9 个答案:

答案 0 :(得分:321)

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

git difftool使用GUI diff程序(即Meld)显示差异,而不是在终端中显示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的方式完全相同。 e.g。

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 mergetool?

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以常规方式执行合并。 e.g。

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

现在可以使用Mergetool来解决合并冲突。您可以通过以下方式轻松启动它:

git mergetool

如果配置正确,Meld窗口将打开,显示3个文件。每个文件都将包含在其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".

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

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

在两种情况下,中间窗格是您应编辑以解决合并冲突的文件。区别在于您喜欢的起始编辑位置; $MERGED表示包含部分合并文件的文件,其中包含合并冲突信息,$BASE表示$LOCAL$REMOTE的共享提交祖先。 [由于两个cmd行都很有用,我将它们保存在我的.gitconfig文件中。大部分时间我使用$MERGED行并注明$BASE行,但如果我想使用$BASE行,则可以交换注释。]

关于输出文件的注意事项:不要担心--output "$MERGED"cmd使用了$MERGED,无论$BASE行中是否使用了cmd--output$MERGED选项只是告诉Meld git想要保存冲突解决文件的文件名.Meld会将您的冲突编辑保存在该文件中,无论您使用$BASE还是.orig作为开始编辑点。

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

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

此时您现在可以提交提交更改。

如果在编辑Meld中的合并冲突时,您希望放弃使用Meld,然后退出Meld而不保存中间窗格中的合并解析文件。 git将回复消息Was the merge successful? [y/n],然后询问n,如果您回答.orig,则合并冲突解决方案将中止,文件将保持不变。请注意,如果您在任何时候将文件保存在Meld中,那么您将不会从git收到警告和提示。 [当然你可以删除文件并将其替换为git为你制作的备份git mergetool文件。]

如果你有超过1个包含合并冲突的文件,那么git将逐个打开一个新的Meld窗口,直到它们全部完成。他们不会同时打开,但当你完成一个冲突的编辑,并关闭Meld时,git将打开下一个,依此类推,直到所有合并冲突都解决了。

live 项目中使用cmd之前,创建一个虚拟项目来测试cmd的使用是明智的。请确保在测试中使用包含空格的文件名,以防操作系统要求您转义cmd行中的引号,请参阅下文。

转义引号字符

某些操作系统可能需要在cmd = meld \"$LOCAL\" \"$REMOTE\" 中对引号进行转义。经验不足的用户应该记住,配置命令行应该使用包含空格的文件名进行测试,如果cmd = meld \\\"$LOCAL\\\" \\\"$REMOTE\\\" 行不使用包含空格的文件名,那么请尝试转义引号。 e.g。

cmd

在某些情况下,可能需要更复杂的报价转义。下面的Windows路径链接的第一个包含三个转义每个引用的示例。这是一个镗孔,但有时是必要的。 e.g。

meldc

Windows路径

Windows用户可能需要向Meld cmd行添加额外配置。他们可能需要使用cmd的完整路径,该路径旨在从命令行在Windows上调用,或者他们可能需要或想要使用包装器。他们应该阅读下面链接的 StackOverflow 页面,这些页面是关于为Windows设置正确的Meld meldc行。由于我是Linux用户,因此无法测试各种Windows path行并且没有关于该主题的更多信息,除了建议使用我的示例并添加Meld的完整路径或Text Filters ,或将Meld程序文件夹添加到All whitespace

使用Meld忽略尾随空格

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

在首选项Leading whitespace标签中,有几个有用的过滤器可以在执行差异时忽略注释等内容。虽然有些过滤器可以忽略Trailing whitespaceText Filters,但是没有忽略# Use either of these regexes depending on how comprehensive you want it to be. [ \t]*$ [ \t\r\f\v]*$ 过滤器(这在Meld邮件列表中已被建议添加,但在我的版本中不可用)。

忽略尾随空格通常非常有用,尤其是在协作时,可以使用Meld首选项{{1}}选项卡中的简单正则表达式轻松手动添加。

{{1}}

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

答案 1 :(得分:57)

虽然另一个答案是正确的,但这是继续将Meld配置为视觉差异工具的最快方法。只需复制/粘贴此内容:

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

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

附注:Meld is surprisingly slow在比较CSV文件时,我发现没有Linux差异工具比这个名为Compare It!的Windows工具(2010年最后一次更新)更快。

答案 2 :(得分:45)

适用于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不同,请更新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

答案 3 :(得分:18)

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

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

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

然后你可以运行

git meld

答案 4 :(得分:1)

这是主要针对使用Windows的开发人员的答案,因为 diff工具的路径语法与其他平台不同。

我将Kdiff3用作git mergetool,但要将git difftool设置为Meld,我 首先从Meldmerge.org安装了最新版本的Meld 然后使用以下命令将以下内容添加到我的全局.gitconfig中:

git config --global -e

注意,如果您想将Sublime Text 3(而不是默认的Vim)用作核心ditor,则可以 将此添加到.gitconfig文件中:

[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 diff。 选项。这将列出Meld内部的已更改文件,当您更改了多个文件时(这确实是非常常见的情况),这非常方便。

.gitconfig文件中 [alias] 部分下方的别名如下所示:

showchanges = difftool --dir-diff

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

git showchanges

下图显示了--dir-diff选项如何显示已更改文件的列表(示例): Meld showing list of files with changes between the $LOCAL and $REMOTE

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

答案 5 :(得分:1)

对于Windows 10,我必须将其放在我的.gitconfig中:

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

您需要知道的所有其他内容,都是由马特斯特(Mattst)在上面的answer中编写的。

PS:出于某种原因,这仅适用于Meld 3.18.x,而Meld 3.20.x给我一个错误。

答案 6 :(得分:0)

从$ MERGED中的不同部分计算头部差异可能很复杂并应用它。在我的设置中,meld通过使用以下方式直观地显示这些差异来帮助:

[merge]
    tool = mymeld
    conflictstyle = diff3

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

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

    在标签1中的
  1. ,您会看到(从左到右)您应在标签2中进行的更改,以解决合并冲突。

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

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

  5. 注意:

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

答案 7 :(得分:0)

我按照这个简单的设置进行融合。 Meld是免费的开源差异工具。对于任何代码更改,您将看到文件和目录的良好并排比较。

  1. 使用yum / apt在Linux中安装融合。
  2. 在〜/ .gitconfig文件中添加以下行
[diff]
    tool = meld
  1. 转到您的代码库,然后键入以下命令,以查看上次提交的更改与当前工作目录(未暂存的未提交更改)之间的区别

git difftool --dir-diff ./

  1. 要查看最后提交的代码和暂存代码之间的区别,请使用以下命令

git difftool --cached --dir-diff ./

答案 8 :(得分:0)

除此之外,对@mattst 的出色回答没有什么可添加的。对于使用适用于 Linux 的 Windows 子系统 (WSL2) 的人,您可以在 Linux 中进行开发,但使用适用于 Windows 的 Meld。

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

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