git archive 是导出指定 commit 干净代码的最轻量可靠方式,直接读取对象数据库打包,不依赖工作区或暂存区,支持按 tag、commit hash、分支及子目录打包,并可通过 --prefix、--worktree-attributes 等参数控制输出格式与内容。

git archive 直接生成指定 commit 的 zip 包
想快速导出某个版本的干净代码(不含 .git 目录、不依赖工作区状态),git archive 是最轻量、最可靠的方式。它不走 checkout,不改当前分支,也不依赖暂存区 —— 只读取对象数据库,直接打包。
常见错误是用 git checkout 切到目标 commit 再手动 zip,既污染工作区,又可能漏掉未跟踪文件或误打包忽略项。
-
git archive --format=zip --output=release-v1.2.zip v1.2:按 tag 打包 -
git archive --format=zip --output=hotfix.zip abc1234:按 commit hash 打包 -
git archive --format=zip --output=main.zip main --prefix=myproject/:加前缀,解压后统一进子目录
排除 .gitignore 里的文件但保留某些“被忽略却要打包”的文件
git archive 默认只打包 Git 跟踪过的文件,自动跳过所有 .gitignore 规则匹配项 —— 这是优点,不是 bug。但如果你有像 config.example 这种被 ignore、却希望出现在发布包里的文件,它不会出现。
原因很简单:archive 不看工作区,只看索引(staging)。没 git add 过的文件,哪怕在磁盘上存在,archive 也看不见。
- 必须先
git add -f config.example强制加入索引(即使被 ignore) - 再
git commit或直接git archive引用该 commit - 临时方案:用
git archive ... | tar --delete '.gitignore'不现实 —— zip 格式不支持流式删文件,得换--format=tar+tar --delete,但复杂度陡增,不推荐
Windows 上中文文件名乱码?用 --worktree-attributes 配合 export-ignore
默认情况下,git archive 在 Windows 下生成的 zip,中文路径常变成乱码(尤其是用第三方解压工具打开时)。这不是编码问题,而是 zip 标准本身对 UTF-8 路径支持不一致导致的。
真正可控的解法是让 Git 主动过滤掉有问题的文件名,或改用更兼容的方式:
- 在
.gitattributes里写:* export-ignore(慎用,会全局跳过) - 更稳妥的是加
--worktree-attributes参数,使 archive 尊重工作区的.gitattributes设置,配合export-subst做变量替换 - 实在不行,改用
tar:git archive --format=tar --output=dist.tar HEAD,再用 7-Zip 或tar -xf解压(Linux/macOS 原生支持,Windows WSL 也可)
想打包子目录而不是整个仓库?路径参数别漏掉冒号
很多人试 git archive HEAD src/ 发现报错或打包空内容 —— 因为 git archive 的路径语法要求明确区分 rev 和路径,中间必须用冒号隔开。
错误写法:git archive HEAD src/(会被当成两个独立参数,src/ 被忽略)
- 正确写法:
git archive HEAD:src/ --format=zip --output=src-only.zip - 也可以写成:
git archive refs/heads/main:lib/ --format=zip -o lib.zip - 注意:
HEAD:src/中的src/必须存在于该 commit 的树中,否则报fatal: Not a valid object name
archive 的边界很清晰:它只打包 Git 知道的快照,不碰工作区、不执行钩子、不解析 submodule(除非显式加 --recursive)。最容易被忽略的是——它完全不关心你本地改了什么,只看你指定的那个 commit 里到底存了哪些文件。











