所以我使用git-subtree在repoA的子目录中有各种repoB分支,就像这样
git clone repoA
cd repoA
// some commits to repoA here
git subtree add --prefix=src/dirA repoB branchA
我使用
在repoA中做了一些提交git subtree push --prefix=src/dirA repoB branchA
一段时间后,我从另一个repoC中提交了一些repoB / branchA,其中branchA也是使用git-subtree添加的。
现在,我试试
git subtree pull --prefix=src/dirA repoB branchA
但是,我没有明显的理由发生合并冲突。这些变化很简单,根本没有冲突 - 正如补丁所证实的那样。
我不确定如何修复此错误。我已经找到了两个其他四个处理相同/类似问题的线程:
我不确定这与不同的SHA-1有关,因为我没有重新提交我的提交,也没有编辑它们;链接1至3。
我的问题更像是链接4,其中git神奇地无法进行简单的合并。但是,链接3讨论了子树合并策略,特别是git-subtree,所以我不确定这在我的情况下是否适用。
情况看起来是一样的:
<<<<<<< HEAD
=======
// changes from commit I try to pull from repoB/branchA
>>>>>>> {commit SHA-1 from commit I try to pull from repoB/branchA}
所以我注意到BASE在三向合并窗口(kdiff3)中显然是错误的。但是,如果是这种情况,为什么git尝试不应用所有早期的提交?发布
git log --oneline
在合并失败之后但在合并/尝试合并之前显示在违规提交之前没有重复的提交。 显示为BASE的文件版本是我第一次发布时的文件
git subtree add --prefix=src/dirA repoB branchA
内部repoA。
那是怎么回事?似乎与git子树由于某种原因无法找到我的提交有关,但它并没有尝试将提交从BASE应用到HEAD~1,而只是我实际上缺少的提交,HEAD。
如何在不搞砸任何存储库历史的情况下修复此错误?为什么不能git拉这个简单的提交,而是认为这是合并冲突?
非常感谢任何见解。
答案 0 :(得分:27)
好的,所以我想出来了。这是一个双管齐下的问题。首先,我的树实际上看起来像这样:
我的树中有一个提交src/dirA
,但在repoB/branchA
已经移动时尚未推送。
我发现git subtree pull
找不到正确的基础,因为它正在寻找一个共同的祖先,因此它在我最后合并树时使用了版本,即当我最初称为git subtree add
。
现在,为了解决共同的祖先问题,必须执行git subtree split --rejoin
,它执行敷衍的合并,因此git再次找到正确的基础,即在将提交从repoA
推送到{{1 }}
但是,正如您在我的案例中所看到的,repoB/branchA
后跟git subtree split --rejoin
并不能解决我的问题:
由于git subtree pull
创建了触及git subtree split
的所有提交的综合历史记录,而不管它们是否被推送,因此SHA-1总和发散。为了演示目的,我将合成历史分成了自己的分支src/dirA
。
split
当然会在git subtree pull
之后成功。但是,下一个git subtree split --rejoin
将失败,因为git subtree push
和合成树的历史在此之后完全不同。
因此,我必须在违规的非推送提交之前返回并将更改从那里拉入我的分支。由于repoB
通过git subtree split --rejoin
仍然无法找到正确的基础,因此这很复杂。
所以我目前解决我的问题的方法是在违规的非推送git subtree pull
提交之前直接签出提交。然后我做了git merge
后跟src/dirA
。这当然会在我的主树中添加两个合并,我无法弄清楚如何压缩到一个合并中,而且从我在源代码中看到的内容来看,似乎并不是解决该问题的简单方法。 / p>
成功git subtree split --rejoin
后,我将剩余的提交从git subtree pull
分支重新定位到git subtree pull
。现在,SHA-1总和在master
和master_fix
的共享历史记录中匹配。
这当然有一个反叛的常见缺点:如果其他人正在处理repoA/master_fix
,他们的历史将被repoB/branchA
毁掉。
答案 1 :(得分:1)
我遇到了类似的问题,因为 git subtree pull
会因 fatal: refusing to merge unrelated histories
而失败。
对我有用的是直接使用 git merge
,更具体地说:
git merge -s subtree -Xsubtree="$prefix" subremote/branch --allow-unrelated-histories