【问题标题】:Automatic merge conflict resolution自动合并冲突解决
【发布时间】:2019-08-26 08:59:52
【问题描述】:

运行此命令时,index.js 出现合并冲突:

$ git checkout feature
$ git merge master

feature 分支index.js

const a = 1;
const b = 1;

master 分支 index.js(这是 feature 分支诞生的地方)

 const a = 1;

master 分支index.js(当前状态)

 const a = 2;

我想以这样的方式自动解决冲突,以便feature 分支上的index.js 更新为:

const a = 2;
const b = 1;

【问题讨论】:

  • 对!我们都想拥有它......但 git 做不到......也没有任何其他像样的 VCS。合并引擎不能只是猜测如何将代码放在一起......他们会尽力而为,并且鉴于您的两个分支提示(看不到共同的祖先,对吗?)您会遇到冲突。
  • 或许git rerere可以帮您一把?我自己从未使用过它,所以无法真正告诉如何使用它。 git-scm.com/docs/git-rerere
  • 当您完成更多合并后,您会看到许多在文本上无法区分的情况,其中正确的合并分辨率不是您想要的,并且您还将拥有更多使用合并的技巧解决工具,所以做正确的事情,一旦你确定那是什么,大约需要一秒钟。

标签: git merge conflict


【解决方案1】:

就像提到的 cmets 一样,Git 非常擅长决定如何将代码组合在一起。不过,您可能对合并策略选项感兴趣。你可以运行

git merge --strategy-option theirsgit merge --strategy-option ours

在发生冲突时偏向源头或目的地。在此处阅读更多信息:

Resolve Git merge conflicts in favor of their changes during a pull

https://git-scm.com/docs/merge-strategies

【讨论】:

    【解决方案2】:

    我建议不要在这里使用-X ours-X theirs(或它们更长的拼写等价物,--strategy-option ours 等)。

    Git 看到的冲突——记住,Git 逐行工作——是在 merge base 提交中 Git 看到的:

    const a = 1;
    

    在两个分支提示提交之一(我们称之为左侧或ours 之一)Git 看到:

    const a = 1;
    const b = 1;
    

    对于 Git,这看起来像:

    • 在 a=1 行(匹配)添加const b = 1;

    同时,在另一个分支提示提交中,theirs 或右侧,Git 看到:

    const a = 2;
    

    对于 Git,这看起来像:

    • 在 a=1 行删除一行,然后插入 const a = 2;

    两条指令都“触及”a=1 行,因此 Git 声明了冲突。

    如果您告诉 Git 偏爱“我们的”/左侧,Git 将保留 add b = 1 line 指令,并扔掉 删除a = 1 并插入替换行指令。如果您告诉 Git 偏爱“他们的”/右侧,Git 将保留将 a=1 替换为 a=2 的指令,但会丢弃另一条指令。

    无论哪种方式,您都会得到错误的解决方案。正确的解决方案实际上是接受这两个更改即使它们看起来有冲突。 Git 无法自动执行此操作。

    对于这种情况,我喜欢将merge.conflictStyle 设置为diff3。这样,当 Git 将混乱的合并冲突结果留在我的工作树中时,文件显示为:

    <<<<<<< HEAD
    const int a = 1;
    const int b = 1;
    ||||||| merged common ancestor
    const int a = 1;
    =======
    const int a = 2;
    >>>>>>> master
    

    在默认情况下,七个垂直条和const int a = 1; 基线丢失(有时剩余的线被挤压在一起更多)。很难阅读。使用diff3 样式,基线就在那里:你可以看到每个人都从什么开始,并自行决定是进行两种更改,仅进行一项更改,还是第三个更好的替代方案要么。

    (另见http://psung.blogspot.com/2011/02/reducing-merge-headaches-git-meets.html

    【讨论】:

    • 我想知道当我做git pull 时如何让 git 生成这样的 ==== 像你的例子中的东西。我已经有了[pull] rebase = true [merge] conflictstyle = diff3,但它说在我隐藏我的更改之前它不会拉动。然后,如果需要,我会隐藏并着手解决,但是当我执行git pull 时,为什么它不能将事情放在一起解决?我想在 1 个命令中启动进程,而不是 2 个。
    • @Nakilon:rebase = truegit pull 根本不运行 git merge。相反,它运行git rebase 作为它的第二个命令。 (请记住,pull 只是一个方便的快捷方式,意思是 运行 git fetch,然后运行第二个 Git 命令来处理我刚刚获取的内容。重点是 git fetch 只是 获取提交,但不对它们做任何事情,在你得到它们之后,你最终需要对它们做一些事情。就个人而言,我比如在获取步骤和操作之间查看它们的选项,pull 禁止这样做,所以我避免使用pull。)
    • 无论如何,git rebase 需要 stash-or-otherwise-clean-up 步骤。变基本身包括重复的挑选,每个挑选是一种合并形式,但却是一种不寻常的形式。有一种方法可以让git rebase 自动为您运行git stash,但我建议不要这样做。正如我刚刚提到的,我还建议避免 git pull 本身:自己使用各个命令,以便您可以看到自己在做什么(并且可以在对您有用的时候在命令之间停下来)。
    猜你喜欢
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 2014-09-17
    • 2012-03-01
    • 2015-10-15
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多