Git:合并两个分叉、独立的仓库

3

仓库A: 从项目的SVN迁移到git,版本号为r:包括所有的SVN历史记录、标签等,之后进行了一些git开发。

仓库B: 同一项目,但是独立地从SVN迁移,版本号为r+small_number。只有最新的快照被带入git。之后进行了大量独立的开发。

现在我将A合并到了B中。想法是抛弃SVN,在GitHub上的项目存储库的develop分支中继续开发。我使用简单的合并完成了这项工作;幸运的是几乎没有真正的冲突。尽管开发主要在不同的领域,但合并后还需要进行很多清理工作,与git无关。

但是: 现在当我执行例如git rebase -i HEAD~2合并的结果上,我理解这应该让我rebase最后两个提交,我被迎接了一个页面,其中包含了300多个提交--自SVN第一版以来项目的完整历史记录。我因担心弄得更糟而中止了rebase(显然我是一个完全的Git新手)。

这个结果是否是预期的?是否可取?如果不是,如何解决?

请注意,所有的单元测试等都通过了,文件本身也没有问题,只是我不明白git元数据/历史记录发生了什么。

编辑:这是我*认为*现在存储库的样子:

          r         A
... o --- o --- ... o 
                     \ 
               B      \    
    o --- .... o ----  o --- ... o 
   r+small_number      C         HEAD

你正在尝试变基的提交之一是合并提交吗? - Lars Noschinski
@cebewee:不,不是将两个仓库合并的那个合并提交。但它确实是一个合并提交,稍晚一些的。 - Radim
那么,HEAD 之前的合并提交的两个父提交都有 C 作为祖先?你能把这些仓库公开吗? - Lars Noschinski
1个回答

8
我猜测这种行为是因为您试图在合并提交上进行变基。
对于下面的答案,我假设您的历史记录如下,即存储库A和B完全独立:
          r         A
... o --- o --- ... o

o ... o
r'    B

你需要问自己想要达成什么目标?你想要创建一个新的分支C,包含A和B的更改。这里的优先事项是什么?你想要实现正确的历史记录吗,纠正'r'丢失SVN历史记录的事实?还是保持A和B的git历史记录不变很重要?
我的答案假定你想要实现前者。由于A和B都来自非常相似版本的SVN存储库,所以在合并共同历史之前,给它们一个共同的git基础可能是个好主意。因此,在合并之前,理想情况下,你应该有以下情况:
          r          A
... o --- o --- .... o
           \
            \
             o --- .... o
       r+small_number   B

目前,我不确定实现这一目标的最佳方法是什么,但您可以尝试执行git rebase -p --onto r --root B

然后,您只需执行git merge A 和 B,就可以得到历史记录。

          r          A     C
... o --- o --- .... o --- o
           \              /
            \            /
             o --- .... o
       r+small_number   B

C包含了您的所有更改。我建议就这样保留它,不需要进一步的变基。


那第二个图表很好看,那正是我应该做的。太糟糕了。在“r”之前的历史我不关心,事实上,如果必要的话,到现在为止的任何历史都可以被丢弃。我想接受你的答案@cebewee,但请解释一下为什么rebase现在的行为是这样的?除非我运行你建议的“rebase -p --onto”,否则它会永远像这样吗?还是随着我从合并点继续前进,情况会变得平稳?而且,这只是rebase还是合并也受到影响?编辑:我已经超过距离合并点C超过2个提交了... - Radim
原则上,git 在存储库中具有多个根的情况下不会出现问题(这种情况甚至在官方 git 存储库中使用),因此预计 git 可以很好地处理这种情况。此外,合并也不会受到影响。我尝试重现您的情况,但失败了。 - Lars Noschinski
@Radim:当我在合并提交上执行rebase时,我会获取到合并(两个)父提交的合并基之前的所有提交--所以你真的确定这些提交有一个共同的祖先吗? - Lars Noschinski
@Radim:当你在进行变基操作时,使用命令git merge-base <commit>^1 <commit^2>会输出什么内容?其中<commit>是你正在变基的合并提交。 - Lars Noschinski
当在一个看似无害的向后合并3个提交时进行变基时,就会出现奇怪的情况。git merge-base 48be6e1948a^1 48be6e1948a^2输出c0e2b73ecb78e41fe805d2803eb3df9451d642f6。我测试了添加更多提交的情况(进一步远离合并点C);然后变基看起来没问题。所以我猜你的“变基合并”确实是罪魁祸首;我接受你的答案。我将保留这个仓库的两个根,因为你说这不应该是问题。 - Radim
好的,现在更清楚了。有问题的提交是合并c0e2b73ec。计算其父级的合并基础是74c3aa1d,其中不包含您的根提交7dfc5ce044。原因是合并的第一个父级(5410fc2f)基于您的存储库中加入A和B的合并之前的部分。如果您想可视化此过程,我发现qgit绘制的图形比gitk更易读。希望对您有所帮助。 - Lars Noschinski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接