1

有什么方法可以拆分 git bundle 文件?比如说,repo.bundle1 和 repo.bundle2,每个都包含一半的 repo。便携式捆绑包太大,无法传输。

假设不能更改允许传输的最大大小,我还能如何处理这个问题。

4

2 回答 2

1

捆绑包可以是增量的。

他们不能有悬空提交,所以如果你想增量地捆绑一个现有的分支,你必须玩一些游戏。

它们必须“按顺序”应用,以便在应用包时,可以锁定其根提交的父级。(可能有一种方法可以通过浅回购来解决这个问题,但如果你试图最终重建整个回购,那么你就不必担心这一点。)

当然,如果任何单个提交太大(例如由于提交非常大的文件),那将是一个问题。

说你有

       x -- x -- x <--(branch1)
      /
A -- B -- C -- D -- E -- F -- G -- H -- I -- J <--(master)
                \      /
                 o -- o <--(branch2)

并假设您想将其分解为不超过 3 个提交的捆绑包。所以让我们从根开始。我们将逐步移动master分支,所以让我们跟踪它的当前位置。

git checkout master
git tag real_master

现在我们查找 SHA ID C(或查找其他一些引用 的名称C,例如在本例中master~7),然后

git reset --hard master~7

请注意,我正在使用硬重置;这可能不是必需的,但我假设您可以从具有干净工作树的 repo 中执行此操作,并且在这种情况下,进行硬重置可使一切保持良好、简单的状态(无论如何,正如我所见)。

我们已经准备好创建我们的第一个捆绑包

git bundle create 0.bundle master

这个捆绑包包括B,它是 的根branch1,所以我们现在可以捆绑起来branch1

git bundle create 1.bundle master..branch1

这相当于

git bundle create 1.bundle ^master branch1

无论哪种方式,我们都假设接收 repo 已经具有可从 访问的ocmmits master,因此只有x提交将放置在此捆绑包中。

看起来,,,DEF一个合乎逻辑的步骤;但F取决于. o_ brnach2所以下一个合乎逻辑的事情就是branch2D. 既然我们还有masteratC我们可以说

git bundle create 2.bundle master..branch2

现在我们需要移动masterG以便我们可以捆绑E,FG. 确保我们master

git reset --hard real_master~3
git bundle create 3.bundle ^branch2 ^master~3 master

在这里,我注意到旧的主线历史和branch2历史都可以从master(通过合并 at F)访问,但由于它们都已经捆绑,我将它们都排除在外。

最后,

git reset --hard real_master
git tag -d real_master
git bundle create 4.bundle master~3..master

在实践中,您可能会在每个捆绑包中使用超过 3 次提交。如果您有一个本身太大的侧枝,您可以使用我们master在此示例中用于分割的相同技术将其分解。

现在您可以独立传输这些,并从它们中获取(或拉取)以在另一端重建 repo。

更新

两个附加说明:


首先,与 ElpieKay 建议使用ddand相比cat,上述方法有利有弊。

它只依赖于 git 本身(尽管dd/cat方法所需的实用程序通常随 git 一起提供)。

每个单独的包文件本身都是有用的,而如果您将文件分段,则dd必须重建所有部分以确保您有一个可用的包。这也意味着您可以保存捆绑包并将它们与您稍后创建的其他捆绑包结合起来(随着更多更改发生);但这只有在您需要从头开始创建另一个新的远程仓库时才有意义。

实际上,只是来回传送增量更改,双方已经有一个共同的提交基线,是捆绑的基本用例。因此,您可能决定使用dd/cat方法最初创建远程存储库,然后使用增量捆绑包进行后续更新共享。

dd/方法的最大优点cat是它非常死记硬背/可编写脚本(即假设工具在手边很简单),而您必须考虑如何为上述方法划分提交;如果结果证明是一个,那么该dd方法还可以拆分一个令人讨厌的大提交。


我最初也忘了提到,您可以列出要包含在捆绑中的多个分支。因此,例如,如果您的阈值更像是每个捆绑包 8 次提交,您可以

1) 移动masterE

2) 捆绑masterbranch1作为 0.bundle

3) 移masterJ

4) 捆绑master不包括master~51.bundle

并完成。

于 2017-11-08T14:19:02.020 回答
1

该命令dd可以将文件拆分为多个部分。cat可以将部分组合成一个整体。

假设我们发现repo.bundle是 1466712k,大约 1.4g,throught du repo.bundle。并假设限制为 1g。我们可以分成repo.bundle2个文件,一个700m,一个700m多一点,这样就可以传输了。

dd if=repo.bundle bs=1048576 count=700 skip=0 of=repo.bundle1
dd if=repo.bundle bs=1048576 skip=700 of=repo.bundle2

的单位bs是字节,所以1048576也是1m700意味着 700 块。skip是要跳过的块数。因此,第一个dd将前 700*1048576 字节写入repo.bundlerepo.bundle1,第二个dd跳过第一个 700*1048576,然后将其余部分写入repo.bundle2.

将这两个文件传输到另一台机器后,使用cat组合它们:

cat repo.bundle1 repo.bundle2 > repo.bundle

请注意,之后文件的顺序cat很重要。我们可以md5sum用来检查组合repo.bundle是否与原点相同。如果两个文件仍然太大,我们可以将源文件拆分为更多部分。小心skip每一个dd

dd, cat, du,md5sum也可用于git-bash.

于 2017-11-08T15:08:35.157 回答