为什么我不能 git 捆绑所有 parents?

Why can't I git bundle all parents?

我正在尝试创建一个仅包含部分历史记录的 git 包。命令 I 运行 bundle the entire branch 是。 (reference)

git bundle create my.bundle --all

但是,如果我只想将初始提交捆绑到(不包括)特定提交,则正确的 rev-parse 语法是。 (reference)

git bundle create my.bundle dae86e1950b1277e545cee180551750029cfe735^@

但这失败了,git 说...

fatal: Refusing to create empty bundle.

如何创建仅包含 initial-commit 和所有特定修订版之前的历史记录的捆绑包?

编辑

I 说明 git 捆绑包仅适用于标签(或其他引用,如 HEAD)。但是我正在尝试捆绑一系列提交,但是 .. shorthand 是独占的,不会包含初始提交。

简短的回答是你不能——好吧,不是相当。从本质上讲,git bundlegit fetch 的服务器一半:它构建一个文件,当您传输后,您实际上将 交给 git fetch该文件从服务器到客户端。客户端需要该文件包含服务器将传递给客户端的数据类型。

结果是捆绑文件必须包含:

  • 引用名称及其哈希 ID 的列表,加上
  • git fetch 将根据这些哈希 ID 减去
  • 得到的对象
  • 根据客户端的 "I already have ..." 哈希 ID,git fetch 不需要 的对象。

准备捆绑包时,您提供的参数是:

  • 参考名称,以及
  • 如果客户端能够直接连接,基础 客户端会提供的哈希 ID。

在这个由您提供的列表中,没有任何地方可以使用 <em>rev</em>^@ 风格的引用。

你能做什么

可以做的是将参考名称附加到每个头部:

for parent in $(git rev-parse ${rev}^@); do
    git tag bundle-p$parent $parent
done

现在您有实际的引用名称(轻量级标签)指向您想要包含在包中的每个提交。您现在可以提供 --tags='bundle-p*' 作为一组正引用,假设没有其他标签以 bundle-p 开头。 (您可以在之后删除标签以保持这种不变性。如果对您来说更方便,您可以使用带有 --branches='bundle-p*' 的分支名称来代替。)

(请注意,${rev}^@ 应用于根提交时不会产生任何输出。这意味着在这种情况下不会有 bundle-p* 标记。)

如果您的特定停止点是普通(单亲)提交,您可以只将一个引用名称附加到 ${rev}^。在所有情况下,您必须将参考名称附加到您 想要在捆绑包中拥有的端点提交。