合并时使用了什么git合并策略?

时间:2016-04-18 12:01:48

标签: git merge

我刚刚发现recursive合并策略可以有一个ours参数。还有ours策略。

因此,如果有更多的人处理文件并将其推送到远程存储库,但是我来做git pull -s ours,那么我将完全忽略远程更改并将其放入。

我发现这很令人困惑,因为该文件似乎没有任何其他人留下的历史记录。要看到这一点,必须写git log --follow <file>。而且,查看合并提交,没有证据表明该文件已受到影响。

怎么能知道这样的事情发生了什么?是否可以看到使用的合并策略?或者,是否可以看到文件历史记录被更改了?

2 个答案:

答案 0 :(得分:2)

文件历史记录未被更改,并且要显示的合并提交中没有其他更改。使用-X ours-s ours只是说要使用合并树的哪一侧(冲突或始终),因此没有被操纵的历史记录。是否存在-X ours当然是不可检测的。因为你也可以简单地不使用-X ours并解决任何引起冲突的问题,完全取消合并。会是同样的结果。合并的工作是做正确的事。

答案 1 :(得分:1)

(这意味着要添加到Björn Kautler's answer,但格式为y太长,无法发表评论。)

编辑:要查找-s ours合并,请将合并与其第一和第二父母(以及其他父母,如果有)进行比较。如果它与第一个相同,但与其他一个相同,则是使用-s ours完成的合并,或者通过手动解析生成等效的合并。

作为贝壳单线(很好......很长的一条线,未经测试):

git rev-list --merges --parents HEAD |
  while read commit first rest; do
    test $(git diff --name-only $commit $first | wc -l) -ne 0 && continue;
    set -- $rest;
    anydiff=false;
    for i do
      test $(git diff --name-only $commit $i | wc -l) -ne 0 && anydiff=true;
    done;
    $anydiff && echo "merge $commit is (effectively) -s ours";
  done

即,找到可从此处到达的所有合并(HEAD)。虽然有一些:

  • 如果$commit$first(其第一个父级)不同,请跳过:不是-s ours
  • 对于剩下的父母:如果$commit$i不同,请记下它是不同的(此处break也可以为次要加速)。
  • 如果与第一个父母相同,但与其他父母不同,抱怨。

-X ours-s ours之间存在重大差异。它 called out in the documentation

  

[ - s]我们的

     

这解决了任意数量的头,但是合并的结果树始终是当前分支头的树,实际上忽略了来自所有其他分支的所有更改。它旨在用于取代侧枝的旧发展历史。请注意,这与递归合并策略的-Xours选项不同。

我认为这个说明不够强大。虽然我还在努力,但在我的“合并”章节中,我就是这样说的:

我们已经看到了-X theirs选项; -X ours对应Mercurial的:merge-local工具 并简单地选择我们的改变 什么时候发生冲突 对于卡罗尔的合并, 这意味着她会保留爱丽丝的变化 支持Bob的, 虽然她仍然会接受鲍勃的变化 没有冲突的地方。

[...]

除了这些-X选项, git merge提供-s strategy选项。 12 其中大部分都足够专业,我们可以忽略这里, 但我们需要特别召唤一个 因为它容易被滥用。

混淆, git merge提供-s ours, 但是-s ours有一个非常不同的动作-X ours。 Git的-s ours 对应于Mercurial的:local合并工具, 其行动是忽略并丢弃每个目标文件 (或Mercurial中的其他文件), 保持源树与当前提交中的相同。 Git中这种合并的原理用法 是杀掉主题或功能分支, 即,将其带回主线分支。 这使它记录在提交DAG中以进行历史检查, 而从主线分支机构丢弃 所有在其中完成的工作, 将其标记为失败的实验。 (我们当然可以在Mercurial中做同样的事, 使用:local。 但是,Mercurial的分支不能被杀死, 所以没有真正的意义。)

12 这可以拼写为--strategy strategy, 但我发现这实际上更令人困惑 不仅仅是记住-s-X-X代表“延长”。