Command Reference

git-archive 教程

解释如何用 git-archive 从某个提交或树对象导出归档包。

适合谁看
  • 已经会基本提交和分支操作的开发者
  • 想理解命令边界与风险的人
前置知识
  • 知道工作区、暂存区、提交的基本关系
  • 能读懂 `git status` 和简单历史图
常见风险
  • 误把本地整理命令用到共享历史
  • 在没确认恢复路径前直接继续改写历史

一句话理解

git-archive 用于从某个提交或树对象导出归档包。

什么时候适合用

  • 当你需要从某个提交或树对象导出归档包
  • 当你想把这类操作做成稳定流程而不是手工重复
  • 当你需要更准确地理解 Git 在这一步到底记录了什么

基本示例

git archive --format=zip HEAD > source.zip

压缩格式对比

git archive 支持多种格式,最常见的两种是 tar 和 zip:

# tar 格式(Linux/macOS 原生友好)
git archive --format=tar HEAD > source.tar

# tar + gzip 压缩
git archive --format=tar.gz HEAD > source.tar.gz

# zip 格式(Windows 友好)
git archive --format=zip HEAD > source.zip
格式优点缺点适用场景
tar保留权限、符号链接等元数据不压缩,体积大Unix/Linux 分发
tar.gz / tgz高压缩率,Unix 标准Windows 需要额外工具服务器部署、源码发布
zip跨平台通用,Windows 原生支持不支持符号链接和权限跨平台分发、Windows 用户

如果不指定 --format,Git 会根据输出文件后缀自动推断格式。

这类命令通常会改变仓库布局或协作方式,团队内最好先统一约定。

一个更稳的实践建议

先用小范围实验仓库验证流程,再推广到主仓库或自动化。

进阶用法

指定目录前缀

使用 --prefix 可以为归档中的所有文件添加目录前缀,这样解压后文件会放在指定的子目录中:

git archive --format=tar.gz --prefix=myproject-1.0/ v1.0 > myproject-1.0.tar.gz

解压后的目录结构:

myproject-1.0/
├── src/
├── docs/
├── README.md
└── ...

这在发布版本时非常实用,让用户解压后直接得到一个干净的版本目录。

导出指定路径

你可以只导出仓库中的部分目录:

# 只导出 src 目录
git archive HEAD src/ > src-only.tar

# 导出多个指定路径
git archive HEAD src/ docs/ README.md > subset.tar

# 结合前缀使用
git archive --prefix=release/ HEAD src/ docs/ > release.tar

注意:路径参数需要是 Git 跟踪的路径,不能是任意文件系统路径。

特定版本/标签导出

# 导出特定标签
git archive v2.1.0 --format=zip --prefix=myapp-v2.1.0/ > myapp-v2.1.0.zip

# 导出特定提交
git archive a1b2c3d --format=tar.gz > snapshot.tar.gz

# 导出最近的标签
git archive $(git describe --tags --abbrev=0) > latest-release.tar.gz

标签导出是发布流程中的标准做法,确保每次发布都有可追溯的归档文件。

排除文件(export-ignore)

通过 .gitattributes 文件中的 export-ignore 规则,可以在归档时自动排除某些文件:

# .gitattributes
tests/ export-ignore
.github/ export-ignore
.gitignore export-ignore
*.test.js export-ignore
docs/internal/ export-ignore

然后正常执行 git archive,被标记的文件会自动排除在归档之外。这在发布源码时非常有用——用户不需要你的测试文件和 CI 配置。

远程归档

Git 还支持从远程仓库直接创建归档:

# 从远程仓库归档(需要服务器支持)
git archive --remote=git@example.com:repo.git HEAD > remote-source.tar

不过需要注意:大多数 Git 服务器出于安全考虑默认禁用了 upload-archive 功能,所以这个特性在实际中使用较少。

CI 集成:自动生成 tarball

在 CI/CD 流程中集成 git archive 是发布自动化的标准做法:

# GitHub Actions 示例
- name: Create release archive
  run: |
    VERSION=$(git describe --tags --always)
    git archive --format=tar.gz --prefix="myproject-${VERSION}/" "${VERSION}" > "myproject-${VERSION}.tar.gz"
    git archive --format=zip --prefix="myproject-${VERSION}/" "${VERSION}" > "myproject-${VERSION}.zip"

- name: Upload artifacts
  uses: actions/upload-artifact@v4
  with:
    name: release-${{ github.ref_name }}
    path: myproject-*.tar.gz

这条命令在流程里解决什么问题

git archive 从指定提交或树对象导出代码快照,支持 tar 和 zip 等格式,不包含 .git 目录。理解它时,要把它放在"如何向不需要 Git 历史的下游用户发布代码"这个场景中来看。

典型用例

  • 发布正式版本时,用 git archive 导出干净的代码快照供用户下载。
  • 把某个标签或提交打包成 zip 文件,提供给只需要代码而不需要版本历史的场景。
  • 在 CI/CD 流程中,用 archive 生成发布产物,避免把 .git 目录打入最终交付物。

图例理解

归档导出的作用面归档命令负责把仓库中的代码快照导出为独立文件,关键区别在于导出的是纯文件内容而非 Git 历史。
输入
提交或树对象导出格式(tar/zip)
结果
归档文件(tar/zip)不含 .git 目录的代码快照
archive 导出的是纯文件快照,不是 Git 仓库,接收方无法执行 git 操作。

特殊情况与边界

  • 导出的归档文件不包含 .git 目录,接收方无法将其作为 Git 仓库使用。
  • .gitattributes 中的 export-ignore 规则会影响导出的内容,可以在导出时排除测试文件或构建配置。
  • 未跟踪的文件不会被包含在归档中,只有 Git 已跟踪的文件才会被导出。
  • 使用 --prefix 可以为归档中的文件添加目录前缀,解压后文件会放在指定子目录中。

延伸阅读

继续搭配 git status、git log、git show 一起看,通常更容易判断这条命令对历史、索引和工作区分别造成了什么影响。