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

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

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

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

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

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


当前回答

我如何设置和使用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 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]*$

对于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的精彩回答中。

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

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

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

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

然后你就可以跑了

git meld

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

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

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

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

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

(diff) 工具= meld

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

我的小道消息

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

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