' git merge -s subtree'工作不正常

时间:2016-10-10 08:32:49

标签: git github

一周前,我重置了一个“ceph-ansible”的状态。 %current branch中的文件夹,来自相应分支的代码(跟踪github的上游):

# git read-tree --prefix=ceph-ansible/ -u ceph_ansible

然后我做了几处修改,包括:

  1. 重命名文件并提交:

    # git mv site.yml.sample site.yml
    
  2. 进行了一些更改并提交了

  3. 从原始分支机构获取更新:

    # git merge -s subtree --squash ceph_ansible
    
  4. 它说:

      

    自动合并ceph-ansible / site.yml.sample

         

    blablabla

         

    壁球提交 - 不更新HEAD

         

    自动合并进展顺利;在按要求提交之前停止

    我可以看到"我的"删除了ceph-ansible / site.yml(以及我添加的几个新文件),ceph-ansible / site.yml.sample已恢复,并且不包含我的更改(它刚刚恢复到我改变之前的状态。)

    git log ceph_ansible site.yml.sample显示2016年8月26日(=最新更改ceph-ansible分支),我当前%分支的变化是今年10月,所以它不应该是任何冲突。

    我相信这种行为有一些明显的解释。你能帮帮我吗?

    更新:我注意到我的git已经很老了(1.8.3)并且是从源代码tarball(2.10.1)构建的。现在输出是:

    # ~/gitbuild/git-2.10.1/git merge -s subtree --squash ceph_ansible
    fatal: refusing to merge unrelated histories
    

    快速搜索广告显示(Git refusing to merge unrelated histories)默认行为已更改。添加' --allow无关-历史'清除错误消息,但合并本身仍然是错误的(我的更改丢失)。

    此错误消息可能解释了为什么git无法正确合并(因为这些repos没有任何关系,对吧)。有人可以证实这一点吗?没有"合并 - 子树"真的合并分支?

1 个答案:

答案 0 :(得分:1)

我已经将这个问题发布到Git的邮件列表中,很少有人给我一个很好的解释这个行为:

  

ceph_ansible合并时,没有共享历史记录和git   使用空树作为共同的祖先。

     

我想你可能还没有完全理解--squash   flag确实...这就是导致你的问题的原因,而不是-s   选项。

     

squash merge接受将从原点合并的提交   分支并将它们压成一个补丁并将它们应用到   当前分支作为新提交...但是这个新提交不是合并   提交(即,当您使用“git show”等查看它时,提交   将只有一个父母,而不是两个 - 或更多 - 父母喜欢正常   合并提交)。

     

基本上,它是diff plus patch操作的语法糖加上   一些Git善良包裹着它,使它更容易使用。

     

但最终一旦完成,Git就不知道这个新的提交   与原始分支有任何关系。接下来呢   你合并的时候,Git不知道有一个以前的合并和   它会尝试从头开始合并所有内容而不是从头开始   上一个常见的合并点。

     

所以要么你必须使用正常的非压缩合并,要么就是你   您不需要在项目中携带ceph_ansible历史记录   在某处记录原始的上游提交(可能在   提交读取树结果时提交消息),然后询问git   在后续合并期间使用它作为合并基础(将会   需要使用管道代码,因为git-merge想要计算合并   基地本身)。

     

git subtree命令(来自contrib)允许另一种方式:它   压缩合并子项目的历史(就像使用交互式rebase一样)   'squash'),然后合并这个壁球提交。