6

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

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

如何将 git 存储库作为孤立的分支导入?我想保留我的承诺。

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

4

1 回答 1

7

我认为你看错了。事实上,这个问题的存在暗示了一些不真实的东西。我认为你想要的更正确地命名为“不相交的子图”。

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

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

假设您有一些存储库,并且在此存储库中有两个名为Xand的分支Y(不master,只是XY)。X提交的分支点和提交a123456的分支Yb987654。这些提交像往常一样指向他们的父母,但是如果我们绘制整个提交图(存储库很小,所以这很适合这个 SO 答案)我们得到:

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

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

有两种不同的根提交。分支X指向a123456哪个是根为 的四提交链的尖端a000000。分支Y指向b987654哪个是根为 的六提交结构的尖端合并提交b000000

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

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


如果你选择X,你为什么选择那个?如果你选择Y,你为什么选择那个?如果您选择两者,我认为您可以证明该选择是合理的;但如果你都没有回答,我会认为这是正确的,并注意你现在已经同意 Git。

(如果您同时选择XY,那么您称这些“孤儿分支”的原因是什么?我认为您可以将此作为正确答案进行争论,并通过说两者都没有连接到来证明这一点master。如果我们随后添加了一个名为master并使其指向 上的四个提交中的任何一个X,然后您会说该分支Y是孤立的并且X不是。如果您master指向 上的六个提交中的任何一个Y,那么您会说那X是孤立的并且Y不再是孤儿。可能有更多的方法来决定,这取决于你想如何定义“孤儿”。但这不是 Git 的意思,事实上,还有更好的术语,它不会与 Git 意见相左,从长远来看会更好地为您服务。)

不相交的子图

在我们上面的练习示例存储库中,既不是孤立分支X也不Y是孤立分支,因为它们都有提交。在图论中——Git 存储库是围绕图论构建的——两个分支名称XY指向整个图的不相交子图。

旁注:Git 所说的孤立分支是什么意思

在 Git 中,用创建的孤儿分支是处于特殊状态“尚未诞生”的分支。这种状态一直持续到分支上有提交,之后分支不再是“孤立分支”。现在它只是一个普通的分支,和其他分支一样。git checkout --orphan newbranch

Git 实际上以一种导致抽象泄漏相当严重的方式实现了孤立分支状态。具体来说,它将新的分支名称写入HEAD,但没有写入其他地方。由于HEAD包含当前分支的名称,如果您检出任何其他分支,则会覆盖该HEAD文件,并且孤立分支本身会完全消失。换句话说,只有一个分支可以处于“孤儿”状态,并且它通过将其名称存储在HEAD并且仅在HEAD. 由于HEAD存储了当前分支的名称,因此只有当前分支可以是孤儿。

最后,我认为您的问题的真正答案是

给定两个不相关的存储库R1R2,您想要创建一个联合存储库(可能是一个新的存储库R3,可能只是修改两个原始存储库之一),其提交图是一个不相交的图,由联合R1中的两个提交图和R2

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

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

$ mkdir r3 && cd r3 && git init

现在将所有内容从R1获取到R3。您可以通过将R1添加为命名远程来做到这一点(如果您将R2添加到R1中,这几乎肯定是要走的路,尽管我们现在在R1添加R2而不是在R3添加R1)。您可以运行git fetch并给它一个 URL 并使用它放入的分支信息FETCH_HEAD,但让我们将两者都添加为远程。这里的<url>s 可以像往常一样是路径 ( ../../otherrepo.gitor /path/to/otherrepo.git) 或ssh://...or git://...or 。https://...

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

$ git remote add r1 <url for r1>
$ git remote add r2 <url for r2>
$ git fetch r1; git fetch r2

至此,您基本上完成了:您将联合作为新存储库中的提交图。唯一要做的就是使本地分支名称指向与部分或所有远程跟踪分支相同的提交。

由于我们将存储库命名为R1 r1,它的所有分支都位于. 同样,由于我们命名为R2,它的所有分支都在. 您可以通过它们的缩短版本来参考这些,并且. 假设有分支和并且有分支和。refs/remotes/r1/branch-name r2refs/remotes/r2/branch-namer1/whateverr2/whateverr1masterAr2masterB

因为只有一个A,你可以这样做:

$ git checkout A

你现在有一个名为A指向与 . 相同的提交的分支r1/A。此外,您的本地A设置为 track r1/A:也就是说,它的上游是r1/A.

对于B.

您可以创建一个新master的 inr3但它只能指向与其他两个存储库之一相同的提交,并且您不能使用此快捷方式。假设您希望r3'smaster匹配r2/master

$ git checkout -b master r2/master

将创建它并将其设置为 track r2/master

如果您不想要此上游--track设置,请使用--no-track.

这就是它的全部内容:创建这两个不相交的子图真的很容易。你只需要知道这就是你正在做的事情,并且只有当你想有机地增长一个新的不相交的子图而不是从某个现有的存储库中获取它--orphan时才需要大惊小怪。

于 2016-05-23T19:40:19.957 回答