![](/img/trans.png)
[英]How to use Meld as git mergetool & difftool on WSL2?
[英]Setting up and using Meld as your git difftool and mergetool
尽管此问题和答案中的大部分信息都可以在StackOverflow上找到,但它分布在许多页面和其他错误或误导性的答案中。 我花了一段时间才把我想知道的一切拼凑起来。
有很多不同的程序可以用作你的 git difftool 和 mergetool,当然对于哪个是最好的没有共识(意见、要求和操作系统会明显不同)。
Meld 是一种流行的免费、开源和跨平台(UNIX/Linux、OSX、Windows)选择,如StackOverflow问题“ 什么是 Git 的最佳可视化合并工具?”中所示。 ,其中提出 Meld 的答案的投票数是任何其他工具的 3 倍以上。
以下2个问题将在我的回答中得到回答:
注意: difftool 和 mergetool 不必使用相同的程序,可以为两者设置不同的程序。
git difftool使用 GUI 差异程序(即 Meld)显示差异,而不是在终端中显示差异输出。
虽然您可以使用-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 窗格的顺序可以通过cmd
中$LOCAL
和$REMOTE
的顺序来控制,即哪个文件显示在左窗格中,哪个文件显示在右窗格中。 如果您希望它们反过来,只需像这样交换它们:
cmd = meld "$REMOTE" "$LOCAL"
最后, prompt = false
行只是停止 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
将包含带有合并冲突信息的部分合并文件(即包含所有>>>>>>>
和<<<<<<<
条目的文件)。
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".
选择是在$LOCAL
和$REMOTE
之间使用$MERGED
还是$BASE
。
无论哪种方式,Meld 都会在左右窗格中显示 3 个窗格,其中$LOCAL
和$REMOTE
以及在中间窗格中显示$MERGED
或$BASE
。
在这两种情况下,中间窗格都是您应该编辑以解决合并冲突的文件。 不同之处在于您更喜欢哪个起始编辑位置; $MERGED
用于包含具有合并冲突信息的部分合并文件的文件,或$BASE
用于$LOCAL
和$REMOTE
的共享提交祖先的文件。 [由于两个cmd
行都很有用,我将它们都保存在我的.gitconfig
文件中。 大多数时候我使用$MERGED
行并且$BASE
行被注释掉,但是如果我想使用$BASE
行代替注释掉可以交换。]
关于输出文件的注意事项:不要担心--output "$MERGED"
会在cmd
中使用,无论之前在cmd
行中是否使用了$MERGED
或$BASE
。 --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]
Was the merge successful? [y/n]
,如果您回答n
则合并冲突解决将中止,文件将保持不变。 请注意,如果您在任何时候将文件保存在 Meld 中,那么您将不会收到来自 git 的警告和提示。 [当然你可以删除该文件并用 git 为你制作的备份.orig
文件替换它。]
如果您有超过 1 个文件存在合并冲突,那么 git 将为每个文件打开一个新的 Meld 窗口,一个接一个,直到它们全部完成。 它们不会同时打开,但是当您完成对一个冲突的编辑并关闭 Meld 时,git 会打开下一个,依此类推,直到所有合并冲突都已解决。
在实际项目中使用git mergetool
之前,创建一个虚拟项目来测试它的使用是明智的。 确保在测试中使用包含空格的文件名,以防操作系统要求您转义cmd
行中的引号,请参见下文。
某些操作系统可能需要对cmd
中的引号进行转义。 经验不足的用户应该记住,配置命令行应该使用包含空格的文件名进行测试,如果cmd
行不适用于包含空格的文件名,请尝试转义引号。 例如
cmd = meld \"$LOCAL\" \"$REMOTE\"
在某些情况下,可能需要更复杂的引号转义。 下面的第一个 Windows 路径链接包含对每个引号进行三次转义的示例。 这很无聊,但有时是必要的。 例如
cmd = meld \\\"$LOCAL\\\" \\\"$REMOTE\\\"
Windows 用户可能需要在 Meld cmd
行中添加额外的配置。 他们可能需要使用meldc
的完整路径,该路径旨在从命令行在 Windows 上调用,或者他们可能需要或想要使用包装器。 他们应该阅读下面链接的StackOverflow页面,这些页面是关于为 Windows 设置正确的 Meld cmd
行的。 由于我是 Linux 用户,因此我无法测试各种 Windows cmd
行,并且除了建议使用我的示例并添加 Meld 或meldc
的完整路径,或者将 Meld 程序文件夹添加到你的path
。
Meld 有许多可以在 GUI 中配置的首选项。
在首选项Text Filters
选项卡中,有几个有用的过滤器可以在执行差异时忽略诸如注释之类的内容。 虽然有过滤器可以忽略All whitespace
和Leading 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 工具比这个名为Compare It 的 Windows 工具更快! (最后更新于 2010 年)。
对于 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
我更喜欢将 meld 设置为单独的命令,如下所示:
git config --global alias.meld '!git difftool -t meld --dir-diff'
这使它类似于此处的 git-meld.pl 脚本: https ://github.com/wmanley/git-meld
然后你可以运行
git 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
您需要知道的所有其他内容都写在上面的 mattst 的这个很棒的答案中。
PS:出于某种原因,这只适用于 Meld 3.18.x,而某些 Meld 3.20.x 版本给我一个错误。 正如 TomasMolina 在下面的评论中提到的,它应该与 Meld 3.20.4 一起使用。
我按照这个简单的设置进行了融合。 Meld 是免费的开源差异工具。 您将看到任何代码更改的文件和目录的并排比较。
[diff] tool = meld
git difftool --dir-diff ./
git difftool --cached --dir-diff ./
从 $MERGED 的不同部分计算你头脑中的差异并应用它可能很复杂。 在我的设置中,meld 通过直观地向您展示这些差异来帮助您,使用:
[merge]
tool = mymeld
conflictstyle = diff3
[mergetool "mymeld"]
cmd = meld --diff $BASE $REMOTE --diff $REMOTE $LOCAL --diff $LOCAL --output $MERGED
它看起来很奇怪,但提供了一个非常方便的工作流程,使用三个选项卡:
在选项卡 1 中,您会看到(从左到右)您应该在选项卡 2 中进行的更改以解决合并冲突。
在选项卡 2 的右侧,您应用“您应该进行的更改”并将整个文件内容复制到剪贴板(使用 ctrl-a 和 ctrl-c)。
在选项卡 3 中,将右侧替换为剪贴板内容。 如果一切正确,您现在将看到 - 从左到右 - 与选项卡 1 中所示相同的更改(但具有不同的上下文)。 保存在此选项卡中所做的更改。
笔记:
这是一个主要针对使用 Windows 的开发人员的答案,因为 diff 工具的路径语法与其他平台不同。
我使用 Kdiff3 作为 git mergetool,但要将 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 diff。 这将列出 Meld 中更改的文件,这在您更改多个文件时非常方便(确实是一个非常常见的场景)。
别名在 .gitconfig 文件中的[alias]部分下方如下所示:
showchanges = difftool --dir-diff
为了显示我对代码所做的更改,我只需输入以下命令:
git showchanges
下图显示了此 --dir-diff 选项如何显示已更改文件的列表(示例):
然后可以单击每个文件并显示 Meld 内部的更改。
除了这个,@mattst 的优秀答案没有什么可补充的。 对于使用 Windows Subsystem for Linux (WSL2) 的人,您可以在 Linux 中进行开发,但使用 Meld for Windows。
cmd = "/mnt/c/Program Files (x86)/Meld/Meld.exe" "$LOCAL" "$REMOTE"
一个警告:我的所有代码都在 Windows 驱动器上,而不是 WLS2 虚拟驱动器上,所以是 YMMV。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.