git-subtree拉合并冲突

FRo*_*Rob 15 git git-subtree

所以我使用git-subtree在repoA的子目录中拥有repoB的各种分支,就像这样

git clone repoA
cd repoA
// some commits to repoA here
git subtree add --prefix=src/dirA repoB branchA
Run Code Online (Sandbox Code Playgroud)

我在repoA中使用了一些提交

git subtree push --prefix=src/dirA repoB branchA
Run Code Online (Sandbox Code Playgroud)

一段时间后,我从另一个repoC中提交了一些repoB/branchA,其中branchA也是使用git-subtree添加的.

现在,我试试

git subtree pull --prefix=src/dirA repoB branchA
Run Code Online (Sandbox Code Playgroud)

但是,我没有明显的理由得到合并冲突.这些变化很简单,根本没有冲突 - 正如补丁所证实的那样.

我不确定如何解决这个错误.我已经找到了另外四个处理相同/类似问题的线程:

  1. git-subtree拉动并发症
  2. git subree pull -P无论<repo> <ref>总是合并冲突
  3. 从中央回购中拉出git-subtree冲突
  4. 合并一个简单的上游更改时,Git子树合并报告会发生冲突(这一点与子树合并策略有关,见下文)

我不确定这与不同的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}
Run Code Online (Sandbox Code Playgroud)

所以我注意到BASE在三向合并窗口(kdiff3)中显然是错误的.但是,如果是这种情况,为什么git尝试不应用所有早期的提交?发行

git log --oneline
Run Code Online (Sandbox Code Playgroud)

在合并失败之后但在合并/尝试合并之前,在违规提交之前没有显示重复的提交.显示为BASE的文件版本是我第一次发布时的文件

git subtree add --prefix=src/dirA repoB branchA
Run Code Online (Sandbox Code Playgroud)

里面的repoA.

发生什么了?似乎与git子树由于某种原因无法找到我的提交有关,但它并没有尝试将提交从BASE应用到HEAD~1,而只是我实际上缺少的提交,HEAD.

如何在不搞砸任何存储库历史记录的情况下修复此错误?为什么git不能拉这个简单的提交而是认为这是合并冲突?

任何见解都将非常感激.

FRo*_*Rob 29

好的,所以我想出来了.这是一个双管齐下的问题.首先,我的树实际上看起来像这样:

现状

我的树上有一个触摸的提交src/dirA,但是当repoB/branchA它已经移动时尚未被推动.

我发现git subtree pull找不到正确的基础,因为它正在寻找一个共同的祖先,因此它在我上次合并树时使用了版本,即我git subtree add最初打电话时.

现在,为了解决共同的祖先问题,必须git subtree split --rejoin执行一个敷衍的合并,因此git再次找到正确的基础,即在提交推repoA送到之后repoB/branchA.

但是,正如你在我的案例中所看到的,a git subtree split --rejoin后跟a git subtree pull并不能解决我的问题:

git子树拉后的破历史.

由于git subtree split创建了所有提交的合成历史,src/dirA而不管它们是否被推动,因此SHA-1总和不同.split为了演示目的,我将合成历史分成了自己的分支.

git subtree pull当然会成功git subtree split --rejoin.然而,接下来git subtree push会失败,因为之后repoB和合成树的历史完全不同.

因此,我必须在违规的非推送提交之前返回并将更改从那里拉入我的分支.这git subtree split --rejoin仍然是必要的,因为git subtree pullvia git merge仍然无法找到正确的基础.

我问题的最终解决方案

所以我目前解决我的问题的方法是在违规的非推送src/dirA提交之前直接签出提交.然后我做了一个git subtree split --rejoin跟着一个git subtree pull.这当然会在我的主树中添加两个合并,我无法弄清楚如何压缩到一个合并,并且从我在源代码中读到的内容,似乎没有一个简单的解决方案来解决这个问题.

成功之后git subtree pull,我将剩余的提交从我的master分支机构改为master_fix.现在,SHA-1资金匹配整个的共同的历史repoA/master_fixrepoB/branchA.

这当然有一个通常的缺点:如果其他人正在努力master,他们的历史将被破坏git branch -m master_fix master.


leo*_*het 5

我遇到了类似的问题,git subtree pull会失败fatal: refusing to merge unrelated histories

对我有用的是git merge直接使用,更具体地说:

git merge -s subtree -Xsubtree="$prefix" subremote/branch --allow-unrelated-histories
Run Code Online (Sandbox Code Playgroud)