当 期间发生冲突时git merge
,我打开一个名为Meld的合并工具。它打开三个文件 LOCAL、BASE 和 REMOTE。正如我所读到的,LOCAL 是我的本地分支,BASE 是共同祖先,REMOTE 是要合并的分支。
现在我的问题是:最终将使用哪个版本的文件?是远程的吗?如果是这样,我可以根据需要编辑它吗,不管 BASE 分支中有什么?
是中间那个:BASE
。
实际上,不是共同祖先,而是冲突用和BASE
标记的半成品合并。>>>>
<<<<
您可以在融合编辑窗口的顶部看到文件名。
BASE
您可以根据需要使用或不使用 meld 命令来编辑文件。
您还可以摆脱 meld 并使用您最喜欢的文本编辑器编辑文件。
<<<< HEAD
和标记之间的代码=====
是合并之前的本地文件之一。====
和之间的代码>>>> <branch name>
是远程文件之一。Meld 有一个隐藏的 3 路合并功能,通过传入第 4 个参数激活:
meld $LOCAL $BASE $REMOTE $MERGED
左右窗格以只读模式打开,因此您不会意外合并错误的方式。中间窗格显示合并的结果。对于冲突,它显示了基本版本,以便您可以看到所有重要的部分:中间是原始文本,两边是冲突的修改。最后,当您按下“保存”按钮时,将写入 $MERGED 文件 - 完全符合 git 的预期。
我使用的 ~/.gitconfig 文件包含以下设置:
[merge]
tool = mymeld
conflictstyle = diff3
[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE $MERGED
这将打开带有 3 个选项卡的融合,第 1 个和第 2 个选项卡包含我要合并的简单差异,默认情况下打开的第 3 个选项卡显示 3 路合并视图。
现在,隐藏该功能的原因是它还不够完善。它现在非常有用,但融合作者 Kai Willadsen 指出需要熨平的皱纹很少。例如,没有 GUI 来启动 3 路合并模式,命令行语法有点神秘,等等。如果你会说 python 并且有一些时间在你手上 - 你知道该怎么做。
编辑:在较新版本的 Meld 中,synax 略有变化。这是在评论中,但它属于答案。
meld 命令现在使用 --output 选项,因此上面代码段的最后一行应该是:
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
涉及4个文件:
$LOCAL
您要合并的分支上的文件;向您展示时不受合并过程的影响
$REMOTE
您要合并的分支上的文件;向您展示时不受合并过程的影响
$BASE
$LOCAL 和 $REMOTE 的共同祖先,即。两个分支开始转移所考虑文件的点;向您展示时不受合并过程的影响
$MERGED
部分合并的文件,有冲突;这是合并过程中唯一涉及的文件,实际上,从未向您显示meld
该$MERGED
文件是包含<<<<<<
, >>>>>>
, =====
(并且,也许,||||||
)标记(用于分隔冲突)的文件。这是您手动编辑以纠正冲突的文件。
手动冲突编辑和视觉冲突编辑是在不同的文件上完成的,并呈现不同的信息。
使用合并工具时(假设meld
),其中看到的文件是:$LOCAL
, $BASE
, $REMOTE
. 请注意,您看不到该$MERGED
文件,尽管这是作为隐藏参数传递的,meld
以便在此处写入编辑结果。
换句话说,在 中meld
,您正在编辑中间的文件,即文件,并且您手动$BASE
从左侧或右侧选择所有更改。这是一个干净的文件,没有被合并过程触及。唯一的问题是,当你保存时,你没有保存到文件中,而是在第四个隐藏参数中,即文件(你甚至看不到)。该文件不包含任何冲突或部分成功的合并,因为它不是该文件。$BASE
meld
$MERGED
$BASE
$MERGED
在可视化编辑中,当向您呈现$BASE
文件(而不是$MERGED
文件)时,git
基本上会丢弃所有尝试进行合并(如果需要,这些尝试在 $MERGED 文件中可见)并让您完全进行合并从头开始。
底线是,在手动和视觉合并冲突中,您查看的不是同一个文件,而是最终结果写入同一个文件(即$MERGED
文件)中。
冲突的手动更正已完成,$MERGED
因为git
无法向您展示三个文件,因此它会压缩该文件中三个文件($LOCAL
, $BASE
, $REMOTE
)中的信息$MERGED
。
但是可视化工具可以向您显示三个文件:它们向您显示$LOCAL
, $BASE
,$REMOTE
文件。您正在从$LOCAL
和$REMOTE
文件中挑选更改,并将这些更改带入$BASE
文件,完全重建甚至覆盖失败的合并尝试,即$MERGED
文件。
Cosmin 的解决方案有效,但$BASE文件已更新——不是$MERGED。这将更新$MERGED文件:
融合:v1.8.4
[merge]
conflictstyle = diff3
tool = mymeld
[mergetool "mymeld"]
cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE --diff $BASE $LOCAL --diff $BASE $REMOTE
使用Meld 1.7,Tomek Bury 的解决方案不再起作用。
默认设置不满足我:
而对于Meld >=1.7,我建议使用其他两种解决方案之一。
第一个解决方案:
meld $LOCAL $BASE $REMOTE --auto-merge
第二种解决方案:
meld $LOCAL $MERGED $REMOTE
.gitconfig
将其复制并粘贴到您的.gitconfig
文件中以获得上述解决方案:
[merge]
tool = meld16
[mergetool "meld17"]
# use this for Meld >=1.7
# see http://stackoverflow.com/a/22911793/859591
# second solution:
cmd = meld $LOCAL $MERGED $REMOTE
# first solution:
#cmd = meld $LOCAL $BASE $REMOTE --auto-merge
[mergetool "meld16"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
[include]
# requires git v1.7.10+
path = .gitconfig.local
.gitconfig.local
如果您在多台机器上使用 .gitconfig ,请将其复制并粘贴到一个文件中,以便仅为这台机器设置 meld17 或 meld16:
# This is a host specific config file!
# Note that git 1.7.10+ is needed
# http://stackoverflow.com/a/9733277/859591
[merge]
tool = meld17
我发现显示的默认文件都没有被保存。meld 显示$LOCAL
,默认情况下$REMOTE
。$BASE
为了使它工作,我需要制作融合显示$MERGED
而不是$BASE
. 把它放在我的~/.gitconfig
固定它为我:
[merge]
tool = mymeld
[mergetool "mymeld"]
cmd = meld "$LOCAL" "$MERGED" "$REMOTE"
我正在使用 Arch,有:
$ git --version
git version 1.8.2
$ meld --version
meld 1.7.1
有关正确答案,请参阅 Saad 的答案。
在 Ubuntu 上使用 meld 1.8.1 我得到了
提供给 --diff 的参数数量错误
并在 $MERGED 之前添加 --output 为我修复它:
[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
由于某种原因,最新版本的融合不显示为冲突添加的标记线 (<<<<<<<, =======, >>>>>>)。如果您想查看这些行,您应该安装 meld v 1.3.3 或更高版本。