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

Make orphaned branch from existing repository?

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

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

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

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

我认为你看错了。事实上,这个问题的存在暗示着一些不真实的东西。我认为您想要的名称更正确 "disjoint subgraphs".

要做到这一点,请耐心等待我完成下一个练习。如果您只想得到答案,请向下滚动。 :-)

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

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

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

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

有两个不同的根提交。分支 X 指向 a123456,这是以 a000000 为根的 four-commit 链的顶端。分支 Y 指向 b987654,这是根植于 b000000.

的 six-commit 结构的尖端合并提交

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

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


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

(如果您同时选择了 XY,您将这些称为 "orphan branches" 的原因是什么?我认为您可以将此作为正确答案进行辩论,并证明它的合理性通过说两个都没有连接到 master。如果我们然后添加一个名为 master 的分支并使其指向 X 上的四个提交中的任何一个,那么你会说分支 Y 是孤立的而 X 不是。如果你让 master 指向 Y 上的六个提交中的任何一个,那么你会说 X 是孤立的并且 Y 不再是孤立的。可能有更多的方法来决定,这取决于你想要如何定义 "orphan" 的曲折程度。但这不是 Git 的意思,并且在事实上,有更好的术语,它不会与 Git 相悖,并且会在较长的 运行 中为您提供更好的服务。)

不相交的子图

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

旁注:Git 的意思是 orphan branch

在 Git 中,一个 orphan 分支 ,使用 git checkout --orphan <em>newbranch[= 创建184=],是一个特殊状态的分支,"yet to be born"。这个状态一直持续到分支上有提交,之后分支不再是"orphan branch"。现在它只是一个普通的分支,和其他分支一样。

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

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

给定两个不相关的存储库 R1R2,您想创建一个联合存储库(可能是一个新存储库 R3,也许只是修改了两个原始存储库之一),其提交图是 disjoint 图,由 R1[ 中的两个提交图合并而成=184=] 和 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> 可以是路径(../../otherrepo.git/path/to/otherrepo.git),或者ssh://...git://...https://...,照常。

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

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

此时您基本上已经完成:您将联合作为新存储库中的提交图。剩下要做的唯一一件事就是使本地分支名称指向与某些或所有 remote-tracking 分支相同的提交。

由于我们将存储库命名为R1r1,它的所有分支都在refs/remotes/r1/<em>branch-name</em>。同样,由于我们命名为R2r2,它的所有分支都在refs/remotes/r2/<em>branch-name</em>。你可以通过他们的缩写版本来引用它们,r1/<em>whatever</em>r2/<em>whatever</em>。假设 r1 有分支 masterA 并且 r2 有分支 masterB.

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

$ git checkout A

你现在有一个名为 A 的分支指向与 r1/A 相同的提交。而且,你的本地A设置为跟踪r1/A:即它的上游是r1/A.

B也是如此。

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

$ git checkout -b master r2/master

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

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

仅此而已:创建这两个不相交的子图真的很容易。你只需要知道这就是你正在做的,只有当你想 有机地增长 一个新的不相交的子图而不是获取时,才需要对 --orphan 大惊小怪它来自一些现有的存​​储库。