git archive是Git原生命令,用于导出指定commit、tag或分支的干净代码快照,仅打包已跟踪文件,不包含.git目录及历史,支持zip/tar等格式,且天然尊重.gitignore规则。

composer archive 命令根本不存在
你在终端输入 composer archive 一定会报错:Command "archive" is not defined。这不是你配置错了,也不是权限问题——Composer 官方二进制从没实现过这个命令。所有文档、教程或 Stack Overflow 回答里提到的 composer archive,要么基于 2018 年就停止维护的第三方插件(不兼容 Composer 2.x),要么是把 git archive 记混了。
想导出不含 .git 的干净源码包?用 git archive + .gitattributes
这是最可靠、可追溯、无需额外依赖的方式。它天然只打包 git ls-files 能看到的文件,自动跳过 .git/、vendor/、node_modules/ 等未跟踪内容。
- 在项目根目录建
.gitattributes,写入要排除的路径(注意语法):tests/** export-ignore docs/** export-ignore .env export-ignore *.log export-ignore
- 确保工作区干净(
git status无未提交变更),并已打 tag(如v1.2.0) - 执行:
git archive --format=zip --output=release-1.2.0.zip v1.2.0 - 生成的 zip 不含
.git目录,也不含任何未git add的文件——这才是真正“不包含 git 信息”的打包
为什么不用 composer.json 的 archive.excludes?
因为那个字段只在 composer archive 命令存在时才生效,而它并不存在。即使你写了:
"archive": {
"exclude": [".git", "/tests/"]
}
,也完全不会被读取——Composer 根本不解析这个字段,除非你装了早已废弃的插件。
更关键的是:archive.excludes 不读 .gitignore,也不受 git status 影响,仅对虚构的 composer archive 命令起作用。你改了它,什么都不会发生。
需要连 vendor 一起打包?别碰 scripts 里的 zip -r
很多团队在 composer.json 的 scripts 里塞 zip -r deploy.zip . -x "vendor/*",这在 CI/CD 或 Windows 上极易失败:
-
zip命令在 Windows cmd 中默认不可用;Git Bash/WSL 和 macOS/Linux 的-x语法也不统一 -
scripts执行时不加载 autoloader,无法做条件判断(比如“只在 tag 构建时打包”) - 没有错误捕获:某次
zip因权限失败,整个流程静默跳过,直到部署时报Class not found
真要带 vendor 打包,先运行 composer install --no-dev --optimize-autoloader,再用 tar 或 7z 手动归档,路径和排除逻辑自己可控,出错立刻可见。











