从现有存储库中创建孤立分支?

时间:2016-05-23 15:46:39

标签: git orphaned-objects

我有一个git存储库,我已经做了一些测试,我想将它包含在主存储库中。

我想将此添加为孤立分支,因为我想保留它,但我不想让我的测试项目膨胀主分支。

如何将git存储库导入为孤立的brach?我想保留我的提交。

编辑以显示它不重复:我实际上并不关心它是孤立的还是类似的东西,我只是想有办法合并2个存储库。给出的答案是正确的,并解决了我的问题。

1 个答案:

答案 0 :(得分:6)

我认为你正在考虑这个错误。事实上,这个问题的存在意味着某些事情并非如此。我认为你想要的是更准确的命名"不相交的子图"。

要到达那里,请耐心等待下一个练习。如果您只想要答案,请向下滚动。 : - )

练习:哪个分支是孤立的?

想象一下,你有一些存储库,在这个存储库中有两个名为XY的分支(没有master,只有XY) 。分支X指向提交a123456和分支Y指向提交b987654。这些提交像往常一样指向他们的父母,但如果我们绘制整个提交图(存储库很小,所以这很适合这个SO答案),我们得到:

o--o--o--o    <-- X

o--o--o---o   <-- Y
    \    /
     o--o

有两种不同的root提交。分支X指向a123456,这是以a000000为根的四个提交链的一角。分支Y指向b987654,这是以b000000为根的六提交结构的提示合并提交。

哪个分支(如果有)是孤儿分支?

(这是停下来思考这个问题的好地方。)

如果您选择X,为什么选择那个?如果您选择Y,为什么选择那个?如果您选择两者,我认为您可以证明这一选择是正确的;但如果你回答既不,我会称之为正确,并注意你现在已经同意Git。

(如果您同时选择了XY,那么您打电话给这些&#34;孤儿分支&#34;的原因是什么?我认为您可以认为这是正确的答案,并且通过说任何一个都没有连接到master来证明它。如果我们然后添加了一个名为master的分支并使其指向X上的四个提交中的任何一个,那么你会说分支Y是孤立的,而X则不是。如果您master指向Y上的六个提交中的任何一个,那么您会说XY孤儿和X不再是孤儿。可能有更多的方法可以决定,这取决于你想要如何定义&#34; orphan&#34;。但那不是什么Git意味着,事实上,有更好的术语,不会与Git不一致,并且从长远来看会更好地为你服务。)

不相交的子图

在我们上面的练习示例存储库中,YX都不是孤儿分支,因为它们都有提交。在图论中,Git存储库是围绕图论建立的 - 两个分支名称Ygit checkout --orphan newbranch指向整个图的不相交的子图

旁注:Git的意思是 orphan branch

在Git中,使用HEAD创建的孤儿分支是一个特殊状态的分支,&#34;尚未出生&#34;。这种状态持续到分支上有提交,之后分支不再是&#34;孤立分支&#34;。现在它只是一个普通的分支,就像其他分支一样。

Git实际上以一种导致抽象泄漏的方式实现了孤立分支状态。具体来说,它将新分支名称写入HEAD,但不在其他地方。由于HEAD包含当前分支的名称,因此如果您检出任何其他分支,则会覆盖HEAD文件,并且孤立分支本身会完全消失。换句话说,只有一个分支可以进入&#34;孤儿&#34;状态,它通过将其名称存储在HEAD并且仅存储在HEAD中来实现。由于$ mkdir r3 && cd r3 && git init 存储当前分支的名称,因此只有当前分支可以是孤儿。

最后,我认为你的问题的答案是

鉴于两个不相关的存储库 R1 R2 ,您想要建立一个联合存储库(可能是一个新存储库 R3 ,也许只是修改一个两个原始存储库中的提交图是一个不相交的图,它是由 R1 R2 中的两个提交图组合而产生的。

让我们将其作为新的第三个存储库。 (通过省略其中一些步骤,将 R1 变成 R2 更容易,反之亦然,所以让我们从完整的练习开始吧如果你愿意,你可以缩小它。)

要构建新存储库 R3 ,首先要创建一个空存储库:

git fetch

现在从 R1 获取所有内容到 R3 。您可以通过将 R1 添加为命名远程来实现此目的(如果您将 R2 添加到 R1 中,这几乎肯定是可行的方法,不过然后我们现在在 R1 中添加 R2 而不是 R3 添加 R1 )。您可以只运行FETCH_HEAD并为其指定一个网址并使用它放入<url>的分支信息,但让我们同时添加两个作为遥控器。这里的../../otherrepo.git可以像往常一样是路径(/path/to/otherrepo.gitssh://...),或git://...https://...$ git remote add r1 <url for r1> $ git remote add r2 <url for r2> $ git fetch r1; git fetch r2

然后,从 R2 获取所有内容到 R3 。我们使用完全相同的步骤,只是一个不同的远程名称和URL:

r1

此时您基本上已经完成了:您在新存储库中将union作为提交图。剩下要做的唯一事情就是使本地分支名称指向与部分或全部远程跟踪分支相同的提交。

由于我们将存储库命名为 R1 refs/remotes/r1/branch-name,因此其所有分支都位于r2中。同样,由于我们将 R2 refs/remotes/r2/branch-name命名为其所有分支都位于r1/whatever中。您可以通过缩短的版本r2/whateverr1来引用这些内容。让我们说master有分支Ar2master分支BA

因为只有一个$ git checkout A ,您可以这样做:

A

现在您有一个名为r1/A的分支指向与A相同的提交。此外,您的本地r1/A设置为跟踪r1/A:即上游为B

同样适用于master

您可以在r3中创建新的r3,但它只能指向与其他两个存储库的一个相同的提交,并且您无法使用此快捷方式。我们假设您希望master r2/master$ git checkout -b master r2/master 匹配:

r2/master

将创建并将其设置为跟踪--track

如果您不想要此上游--no-track设置,请使用--orphan创建分支。

这就是它的全部内容:创建这两个不相交的子图确实很容易。你只需要知道这就是你正在做的事情,只有当你想要增长一个新的不相交的子图有机而不是从某些人那里获取它时,才需要使用{{1}}。现有的存储库。