最终将使用哪个版本的git文件:LOCAL,BASE或REMOTE?


174

当发生冲突时git merge,我打开一个称为Meld的合并工具。它打开三个文件LOCAL,BASE和REMOTE。正如我读到的那样,LOCAL是我的本地分支,BASE是公共祖先,REMOTE是要合并的分支。

现在我的问题是:最终将使用哪个版本的文件?它是远程的吗?如果是这样,无论例如BASE分支中的内容是什么,我都可以根据需要进行编辑吗?

Answers:


142

是中间的一个:BASE

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

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

在此处查看屏幕截图

融合基地

您可以BASE使用或不使用meld命令来编辑文件。
您也可以摆脱掉融合,而只需使用自己喜欢的文本编辑器编辑文件即可。

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

3
如果将merge.conflictstyle配置选项设置为diff3默认值,则某些人会更好地理解文件中的冲突块,这些文件自动合并失败merge
kostix 2012年

3
我实际上看不到HEAD,<<和===唱歌。如果您提供的中间窗口为空。但这只是给其他人的提示,谢谢您的回答。
tsusanka 2012年

如果你没有看到HEAD<<<<<=====标志,它意味着在所有没有冲突。在这种情况下,中间窗口将不会为空,它将显示合并结果,但是将没有“红色”部分
Fabien Quatravaux 2012年

10
当我与Meld合并时,在中间窗格(即BASE版本)中也看不到任何<<<<<<======也没有>>>>>>标记。有时,中间窗格将为空,如aGr所报告。也许这种差异是由于不同的设置。当我开始MELD工具,以下文件存在,假定信息库中的文件的名称是X.javaX.javaX.java.origX.java.BACKUP.#X.java.BASE.#X.java.LOCAL.#X.java.REMOTE.#,其中#一些号码。将合并结果称为BASE版本令人困惑;合并会更好。
Teemu Leisti 2012年

3
实际上,BASE是公共祖先,MERGED是其中包含部分合并信息的文件的名称。请参阅我的问题和答案设置和使用Meld作为您的git difftool和mergetool,确切解释了它的工作方式。HTH。
2015年

107

通过输入第四个参数,Meld具有隐藏的三向合并功能

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个选项卡的融合,第一个和第二个选项卡包含我要合并的简单差异,默认情况下打开的第三个选项卡显示三向合并视图。

现在,隐藏该功能的原因是它还不够完善。它非常有用,但是融合作者Kai Willadsen指出很少需要消除的皱纹。例如,没有用于启动三向合并模式的GUI,命令行语法有点不可思议,等等。如果您会说python并有一些时间在手-您知道该怎么做。

编辑:在较新版本的Meld,该synax已稍有更改。这是在评论中,但它属于答案。

现在,meld命令使用--output选项,因此上面代码段的最后一行应为:

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

7
@ Jesse,@ lumbric,似乎较新版本的meld使用该标志--output表示$ MERGED结果。我在查看git版本附带的融合启动脚本时发现了这一点:github.com/git/git/blob/master/mergetools/meld
Johann

1
@lumbric我相信是的,对于使用的1.7.x +而言--output option。请在启动脚本中查看以下行:"$merge_tool_path" --output "$MERGED" "$LOCAL" "$BASE" "$REMOTE"
Johann

12
在最新版本(版本> 1.8.4)中,我们必须使用--auto-merge选项。cmd = meld --diff $ BASE $ LOCAL --diff $ BASE $ REMOTE-自动合并$ LOCAL $ BASE $
REMOTE-

7
我和使用Meld 1.8.4的@pingpongboss一样存在相同的问题:Meld是在单独的窗格中打开内容,而不是打开第3个选项卡。最终可以正常工作的命令是:cmd = meld $LOCAL $BASE $REMOTE --auto-merge --output $MERGED。因此,这将打开3个选项卡(很好的旧方法),将无冲突的合并自动合并到中间,中间是$ MERGED,并将其用作冲突解决输出。
farmir 2015年

2
输出的语法可以是--output=<file>-o <file>,请参阅meld --help
levsa 2015年

57

涉及4个文件:

  1. $LOCAL您要合并的分支上的文件;显示给您的合并过程未触及

  2. $REMOTE您要合并的分支上的文件;显示给您的合并过程未触及

  3. $BASE$ LOCAL和$ REMOTE的共同祖先,即。两个分支开始转移所考虑文件的位置;显示给您的合并过程未触及

  4. $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文件的失败尝试。


我只是希望有可以显示所有4个文件的工具(例如,无法比较)
yoniLavi 2013年

@yoniYalovitsky:是,或p4merge
2013年

我曾经使用过ClearCase软件包中的合并工具
mishmashru,2015年

@yoniLavi-这些工具可以显示4个窗格,但不一定如此答案中所述全部显示四个文件。特别是,你可以设置这4个窗格的工具来告诉你$LOCAL$REMOTE$BASE和输出最初等于$BASE,但它是由不同$MERGED的,因为它不具备的git的企图文件和冲突标记等合并上。实际上,这就是使用这些工具的方式,它与LOCAL / REMOTE / BASE + OUTPUT的三窗格方法最为相似,后者没有显示合并。第四个窗格仅允许您将基础与输出分开。
BeeOnRope

16

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

我可以确认这一点.Saad的解决方案适用于Ubuntu。就原始问题而言,这是当前的正确答案。
cosmin 2014年

3
在我的Meld-3.11版本中,此命令非常有效:cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE
MartinM 2015年

为什么--diff $BASE $LOCAL --diff $BASE $REMOTE最后需要?对我而言1.8.4可以正常运行(据我cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE
所知

1
@farmir:没必要。它在Meld中又打开了两个选项卡,因此您可以分别查看与BASE相比的LOCAL和REMOTE。
Sam Kauffman

1
无论我使用这些参数按什么顺序排序,三向选项卡始终是第三个选项卡,而默认情况下始终选择第一个选项卡。有没有一种方法可以默认选择三向选项卡?
Sam Kauffman

13

对于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 1.8.4。如果运行cmd = meld $LOCAL $BASE $REMOTE --auto-merge,则中间窗格将是$ BASE,而不是实际用作冲突解决输出的$ MERGE。
farmir 2015年

1
@farmir您选择$ BASE作为第二个选项卡。
Alex78191

11

我发现没有显示任何默认文件。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

请问,此配置与inux兼容吗?
MadMad666 '16


2

请参阅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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.