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

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

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

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

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

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


当前回答

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

[merge]
    tool = mymeld
    conflictstyle = diff3

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

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

在TAB 1中,您可以看到(从左到右)应该在TAB 2中为解决合并冲突所做的更改。 在TAB 2的右侧,你应用“你应该做出的改变”,并将整个文件内容复制到剪贴板(使用ctrl-a和ctrl-c)。 在TAB 3中,用剪贴板内容替换右侧。如果一切正确,您现在将从左到右看到与tab 1中显示的相同的更改(但上下文不同)。保存在此选项卡中所做的更改。

注:

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

其他回答

我如何设置和使用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 difftool的方式完全相同。

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窗口窗格的顺序可以通过cmd中的$LOCAL和$REMOTE的顺序来控制,也就是说哪个文件显示在左边窗格中,哪个在右边窗格中。如果你想让它们反过来,只需像这样交换它们:

    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行,但这超出了本回答的范围。

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

首先是这些参数的含义:

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

我建议你使用其中一种:

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

or:

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

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

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

In BOTH cases the middle pane is the file that you should edit to resolve the merge conflicts. The difference is just in which starting edit position you'd prefer; $MERGED for the file which contains the partially merged file with the merge conflict information or $BASE for the shared commit ancestor of $LOCAL and $REMOTE. [Since both cmd lines can be useful I keep them both in my .gitconfig file. Most of the time I use the $MERGED line and the $BASE line is commented out, but the commenting out can be swapped over if I want to use the $BASE line instead.]

注意输出文件:不用担心——输出“$MERGED”在cmd中被使用,不管之前在cmd行中是否使用了$MERGED或$BASE。——output选项只是告诉Meld git希望将冲突解决文件保存在哪个文件名中。Meld将在该文件中保存您的冲突编辑,无论您是使用$MERGED还是$BASE作为开始编辑点。

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

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

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

If, while you are editing the merge conflicts in Meld, you wish to abandon the use of Meld, then quit Meld without saving the merge resolution file in the middle pane. git will respond with the message file_name seems unchanged and then ask Was the merge successful? [y/n], if you answer n then the merge conflict resolution will be aborted and the file will remain unchanged. Note that if you have saved the file in Meld at any point then you will not receive the warning and prompt from git. [Of course you can just delete the file and replace it with the backup .orig file that git made for you.]

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

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


转义引号字符

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

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

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

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

Windows路径

Windows users will probably need extra configuration added to the Meld cmd lines. They may need to use the full path to meldc, which is designed to be called on Windows from the command line, or they may need or want to use a wrapper. They should read the StackOverflow pages linked below which are about setting the correct Meld cmd line for Windows. Since I am a Linux user I am unable to test the various Windows cmd lines and have no further information on the subject other than to recommend using my examples with the addition of a full path to Meld or meldc, or adding the Meld program folder to your path.

Git Diff和Meld在Windows上 如何设置Meld为git合并工具 Git与Windows上的Meld合并

用Meld忽略尾随空格

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

在首选项文本过滤器选项卡中,有几个有用的过滤器可以在执行diff时忽略诸如注释之类的内容。尽管有过滤器可以忽略所有空白和前导空白,但没有忽略尾随空白过滤器(这已经被建议作为Meld邮件列表中的附加功能,但在我的版本中不可用)。

忽略尾随的空格通常是非常有用的,特别是在协作时,可以在Meld首选项文本过滤器选项卡中使用简单的正则表达式手动添加。

# 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工具Compare It!(最近更新于2010年)。

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

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

git config --global -e

注意,如果你想要Sublime Text 3而不是默认的Vim作为核心编辑器,你可以 添加到.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的差异 选择。这将列出在Meld中更改的文件,当您更改了多个文件时(确实是一个非常常见的场景),这很方便。

别名在.gitconfig文件中,在[alias]部分下面:

showchanges = difftool --dir-diff

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

git showchanges

下图显示了——dir-diff选项如何显示已更改文件的列表(示例):

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

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

使用yum/apt在Linux中安装meld。 在~/中添加以下行。gitconfig文件

(diff) 工具= meld

转到代码repo并输入以下命令查看上次提交的更改与当前工作目录之间的差异(未分阶段未提交的更改)

我的小道消息

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

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

对于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