Git 文件的哪个版本最终将被使用: LOCAL,BASE 还是 REMOTE?

当在 git merge期间发生碰撞时,我打开一个名为 融合的 mergetool。它打开三个文件 LOCAL、 BASE 和 REMOTE。我已经读到 LOCAL 是我的本地分支,BASE 是共同的祖先,而 REMOTE 是要合并的分支。

现在回到我的问题: 最终将使用哪个版本的文件?是遥控的吗?如果是这样,我可以编辑它,因为我想,无论什么是在 BASE 分支例如?

104877 次浏览

就是中间那个 BASE

实际上,BASE不是共同的祖先,而是用 >>>><<<<标记冲突的半成品合并。

您可以看到在融合编辑窗口顶部的文件名。

看这里的截图

meld base

可以根据需要编辑 BASE文件,不管是否使用 meld 命令。
您也可以去掉 meld,只用您喜欢的文本编辑器编辑文件。

  • <<<< HEAD=====标记之间的代码是合并前的本地文件之一。
  • ====>>>> <branch name>之间的代码是远程文件之一。

Meld 通过传递第4个参数来激活 隐藏的3路合并特性:

meld $LOCAL $BASE $REMOTE $MERGED

右窗格和左窗格以只读模式打开,因此您不能意外地以错误的方式合并。中间窗格显示合并的结果。对于冲突,它会显示基本版本,这样您就可以看到所有重要的部分: 中间是原始文本,两边是冲突修改。最后,当您按下“ Save”按钮时,$MERGED 文件被写入——正如 git 所期望的那样。

我使用的 ~/. gitconfig 文件包含以下设置:

[merge]
tool = mymeld
conflictstyle = diff3
[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE $MERGED

这将打开3个标签合并,第一个和第二个标签包含简单的差异,我试图合并,第三个标签,默认打开,显示3路合并视图。

现在,这个功能被隐藏的原因是它还没有被完善。它现在很有用,但是混合体的作者 Kai Willadsen 指出,需要消除的皱纹很少。例如,没有 GUI 来启动3路合并模式,命令行语法有点神秘,等等。如果你会说巨蟒语,并且有时间——你知道该怎么做。

编辑: 在较新版本的 Meld 中,synax 发生了轻微的变化。这是在评论中,但它属于在答案中。

Meld 命令现在使用—— output 选项,因此上面代码片段的最后一行应该是:

cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED

我发现没有一个默认文件被保存。 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

涉及4个文件:

  1. 在你合并的分支上的文件; 当显示给你的时候,合并进程没有碰到它

  2. 从您合并的分支上的文件; 当显示给您时,合并进程没有碰到该文件

  3. $LOCAL 和 $REMOTE 的共同祖先,即。两个分支开始转移所考虑的文件的点; 当显示给您时,合并进程没有触及到 < em >

  4. 部分合并的文件,有冲突; < em > 这是合并过程触及的唯一文件,实际上,在 meld中从未显示给您


$MERGED文件包含 <<<<<<>>>>>>=====(可能还有 ||||||)标记(用于分隔冲突)。这个是编辑 手动操作以纠正冲突的文件。

手动冲突编辑和可视化冲突编辑是在不同的文件上进行的,呈现出不同的信息。

当使用 mergetool (假设为 meld)时,其中看到的文件是: $LOCAL$BASE$REMOTE。请注意,您没有看到 $MERGED文件,尽管这是作为隐藏参数传递给 meld,以便在那里写入编辑的结果。

换句话说,在 meld中,您正在编辑中间的文件,即 $BASE文件,并且您从左侧或从右侧挑选所有的更改。它是一个干净的文件,合并过程不会触及它。唯一的小故障是,当您保存时,您没有保存到 $BASE文件中,而是在 meld的第四个隐藏参数中,即 $MERGED文件(您甚至看不到它)。$BASE文件包含任何冲突或部分成功的合并,因为 它不是 $MERGED文件

在可视化编辑中,当向您显示 $BASE文件(而不是 $MERGED文件)时,git基本上放弃了所有尝试进行合并的尝试(如果您愿意,这些尝试在 $MERGED 文件中是可见的) ,并允许您使用 彻底的进行合并 从头开始

底线是,在手动和可视化合并冲突中,您不会查看相同的文件,但最终结果将写入同一个文件(即 $MERGED文件)。

手动纠正冲突是在 $MERGED上完成的,因为 git 毫无意义提供了三个文件,所以它压缩了 $MERGED文件中三个文件($LOCAL$BASE$REMOTE)的信息。

但是可视化工具 有办法向您显示三个文件: 它们向您显示 $LOCAL$BASE$REMOTE文件。您正在从 $LOCAL$REMOTE文件中挑选更改,并将这些更改放入 $BASE文件中,完全重新构建甚至覆盖合并失败的 $MERGED文件尝试。

由于某些原因,最新版本的 merge 不显示为冲突添加的标记行(< < < < < < < < ,= = = = = = ,> > > > > > >)。如果您想看到这些行,您应该安装 meldv1.3.3或更早版本。

请看 Saad 的正确答案。

在 Ubuntu 上使用 meld 1.8.1,我得到了

提供给—— diff 的参数数目错误

在 $MERGED 为我修复它之前添加——输出:

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

Cosmin 的解决方案起作用了,但是 $基地文件被更新了——而不是 $合并。这将更新 $合并文件:

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

有了 融合1.7的解决方案托梅克伯里不再工作。

默认设置并没有让我满意:

Default settings

对于 融合 > = 1.7,我建议另外两种解决方案中的一种。

第一个解决方案 :

 meld $LOCAL $BASE $REMOTE --auto-merge

first solution

第二个解决方案 :

 meld $LOCAL $MERGED $REMOTE

second solution

。 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文件中,以便只为这台机器设置 meld17或 meld16,以防您使用。多台机器上的 gitconfig:

# This is a host specific config file!
# Note that git 1.7.10+ is needed
# http://stackoverflow.com/a/9733277/859591
[merge]
tool = meld17