如何在没有共同祖先的情况下合并两个分支? [英] How to merge two branches without a common ancestor?

查看:41
本文介绍了如何在没有共同祖先的情况下合并两个分支?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的项目中间开始使用 Git,其中前两次提交只是一些初始设置(.gitignore 和 .gitattributes),第三次提交 M2 添加了SVN中继:

I have started using Git in the middle of my project, where the first two commits are just some initial settings (.gitignore and .gitattributes), and the third commit M2 adds the content of the SVN trunk:

I1 -- I2 -- M2 -- N -- .. -- Z

我在一个名为svn的分支中导入了SVN历史,其中M1是SVN主干(内容与M2相同,除了 .gitignore 和 .gitattributes):

I have imported the SVN history in a branch named svn, where M1 is the SVN trunk (with the same content as M2, except .gitignore and .gitattributes):

A -- B -- ... -- K -- L -- M1

问:合并两个分支的最佳方法是什么?

Q: What is the best approach in merging both branches?

我可以将M1M2合并成M3,然后rebase,但是我不知道如何删除I1I2 提交,如果我可以安全地删除 M3 提交(我找到了一些保留合并提交的建议,但在这种情况下 M3不再需要了).

I could merge M1 and M2 into M3, and then rebase, but I don't know how to delete the I1 and I2 commits and if I can safely remove the M3 commit (I have found some advices to preserve the merge commits, but in this case M3 it's not necessary anymore).

A -- B -- ... -- K -- L -- M1
                             
                              M3 -- N' -- .. -- Z'
                             /
               I1 -- I2 -- M2 -- N -- .. -- Z

另一种方法是挑选 N .. Z 手动提交到 svn 分支,但我想避免这种方法.

Another way would be to cherry-pick the N .. Z commits into svn branch by hand, but I would like to avoid this approach.

最优雅的解决方案是重新定义 N .. Zsvn 分支之上提交的更改,但我没有'还没有找到没有共同祖先的两个分支所需的语法.

The most elegant solution would be to rebase the changes introduced by N .. Z commits on top of svn branch, but I didn't found yet the required syntax for two branches without a common ancestor.

推荐答案

免责声明:我自己只在玩具存储库中使用过一次移植点".但这是一个您可能没有听说过的晦涩功能,并且_可能_对您的情况有所帮助.

您可以使用移植点"来伪造祖先信息.参见,例如,.git/info/grafts 的用途是什么?或继续立即关于嫁接点的 git wiki 条目.

You could use "graft points" to fake the ancestry information. See, e.g., What are .git/info/grafts for? or proceed immediately to the git wiki entry on graft points.

本质上,您将创建一个文件 .git/info/grafts 来诱使 git 认为提交 M1 是提交 M2 的祖先强>:

In essence, you would create a file .git/info/grafts that tricks git into thinking that commit M1 is an ancestor of commit M2:

$ cat .git/info/grafts
<your M2 commit hash> <your M1 commit hash>

随后,看起来 M2 是一个空提交,它只是将 I2M1 合并到一个公共树中.

Subsequently, it would look like M2 was an empty commit that just merged I2 and M1 into a common tree.

主要缺点:未提交嫁接点;因此,它不会被检出,而是需要手动添加到存储库的每个本地工作副本中.

The major downside: the graft point is not committed; therefore, it is not checked out, but needs to be added to each local working copy of the repository manually.

更新: 使用git replace --graft 代替.

如上所述,嫁接点已被取代.运行

Graft points, as described above, have been superseded. Run

git replace --graft <your M2 commit hash> <your M1 commit hash>

创建嫁接.这存储在 .git/refs/replace/ 中.尽管 git 默认不获取或推送这些引用,但它们可以使用以下方法在存储库之间同步:

to create the graft. This is stored in .git/refs/replace/. Although git does not fetch, or push, these refs by default, they can be synchronized between repositories using:

git push origin 'refs/replace/*'
git fetch origin 'refs/replace/*:refs/replace/*'

(StackOverflow:如何在不推送任何其他 git 引用的情况下推送引用/替换"?)

这篇关于如何在没有共同祖先的情况下合并两个分支?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆