繁体   English   中英

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

[英]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个问题将在我的回答中得到回答:

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

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

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

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 会发出提示。


如何设置和使用 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 路径

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

使用 Meld 忽略尾随空格

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

在首选项Text Filters选项卡中,有几个有用的过滤器可以在执行差异时忽略诸如注释之类的内容。 虽然有过滤器可以忽略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 工具比这个名为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 是免费的开源差异工具。 您将看到任何代码更改的文件和目录的并排比较。

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

git difftool --dir-diff ./

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

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. 在选项卡 1 中,您会看到(从左到右)您应该在选项卡 2 中进行的更改以解决合并冲突。

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

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

笔记:

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

这是一个主要针对使用 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 显示在 $LOCAL 和 $REMOTE 之间更改的文件列表

然后可以单击每个文件并显示 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM