git bundle create 必须指定明确的引用范围,如 main^..main,否则报错;需用 --branches=main 显式包含分支引用,解包时通过临时 remote fetch 并 checkout。

git bundle create 命令必须指定明确的引用范围
直接运行 git bundle create my.bundle main 会失败,Git 要求你明确告诉它“这个分支从哪开始打包”。git bundle 不接受单个分支名作为完整历史——它需要一个可解析的 revision range(如 main~10..main 或 --all),否则报错:fatal: Need exactly one revision to bundle。
最常用且安全的做法是用 ^ 表示“该分支所有可达提交”:
git bundle create main.bundle main^..main
这等价于“从 main 的第一个祖先开始,到 main 最新提交为止”,即完整包含 main 分支全部历史(不含其他分支或孤立提交)。若分支从未被 rebase,main^..main 就是它的全部 commit 链。
- 不要用
main..main:结果为空(自身到自身无差异) - 避免
--all:会打包所有 refs(包括 tags、remotes、甚至 stash),体积大且可能含敏感信息 - 如果 main 是空分支(仅初始化,无 commit),
main^会报错;此时需改用$(git rev-list --max-parents=0 main)获取根提交再构造范围
导出时排除不需要的 refs(如远程跟踪分支和未推送的本地提交)
默认情况下,git bundle create 只打包你显式指定的 revision range 对应的 commit 和它们直接关联的 tree/blob,但不会自动包含 branch ref 本身。也就是说,接收方解包后看不到 main 这个分支名——只有 commit 数据。
要让接收方能直接 checkout 出同名分支,必须在 bundle 中显式 include ref:
git bundle create main.bundle main^..main --branches=main
或者更稳妥地,用 --all + 排除策略(但注意副作用):
git bundle create main.bundle --all --exclude=origin/*
-
--branches只打包指定分支名对应的 ref,不打包其他本地分支 -
--exclude必须写完整 ref 名(如origin/main),不能只写origin/;否则 Git 会忽略该排除项 - bundle 文件本身不加密,含敏感 commit message 或文件内容时,导出前应确认无涉密信息
验证 bundle 是否可用:用 git bundle list-heads 检查内容
生成 bundle 后别急着传走,先本地验证它是否真包含你要的东西。最轻量的方法是:
git bundle list-heads main.bundle
输出类似:abc1234567890def main,说明 bundle 包含了 main 分支头指针指向的 commit,并标记为 main ref。
- 如果没看到预期分支名,说明创建时没加
--branches=xxx或范围写错了 - 想看具体有哪些 commit,可用:
git bundle unbundle main.bundle | git show --oneline(注意:此命令不改变工作区,只输出 commit 列表) - bundle 是二进制文件,不可用
cat或文本编辑器查看;误编辑会导致损坏且无法恢复
接收方如何正确解包并重建分支
对方拿到 main.bundle 后,不能直接 git clone(bundle 不是仓库),也不能 git pull(没有 remote)。正确流程分两步:
1. 添加 bundle 为临时 remote:
git remote add bundle-remote /path/to/main.bundle
2. fetch 并检出:
git fetch bundle-remote<br>git checkout -b main bundle-remote/main
- fetch 成功后,
git log bundle-remote/main应与原分支完全一致 - 如果原 bundle 创建时用了
--branches=main,fetch 后bundle-remote/main就存在;否则只能 fetch 到 commit,需手动git checkout -b main abc123... - 解包后默认不包含原仓库的 hooks、config、.gitignore 等非 Git 对象数据——这些得另行同步
bundle 文件本质是 Git 对象的打包快照,不是完整克隆。它省略了 reflog、rebase 中间状态、以及未被任何 ref 引用的 dangling commit。如果你依赖这些细节,bundle 不是合适方案。











