composer如何防止.git目录被包含进发布的包中?(archive exclude配置)

1次阅读

有效写法是配置 .gitattributes 文件而非 composer.json 的 archive,因后者仅用于手动 composer archive 且不参与 packagist/github 自动发布;.gitattributes 中写入 .git export-ignore 即可排除 .git 目录。

composer如何防止.git目录被包含进发布的包中?(archive exclude配置)

composer.json 的 archive 配置怎么写才有效? archive 不是全局配置,只在你用 composer archive 手动打包时起作用,而绝大多数发布场景(比如 Packagist 自动抓取、GitHub Release)根本不会读它。所以别指望靠它防 .git —— 它压根不参与日常发布流程。

真正起作用的是 .gitattributes 文件,Composer 在生成 ZIP 包(例如用户运行 composer install --prefer-dist)时,会尊重 Git 的导出规则。你要做的只是告诉 Git:哪些文件不该进归档。

  • .gitattributes 必须放在项目根目录,且必须提交到仓库里
  • 写法很简单:.git export-ignore(一行即可)
  • 这条规则会跳过整个 .git 目录,也顺带排除 .gitignore.gitmodules

为什么 exclude-from-classmapautoload.exclude 不能防 .git? 这些配置只影响自动加载器的行为,和包分发完全无关。exclude-from-classmap 是让 Composer 在生成 classmap 时跳过某些路径;autoload.exclude(v2.5+)是让 PSR-4/PSR-0 加载器忽略某些文件。它们既不删文件,也不改 ZIP 内容,对 .git 目录毫无约束力。

常见误操作:把 .git 加进 autoload.exclude,结果发现发布的 ZIP 里还是有它 —— 因为 autoload 配置根本不参与归档逻辑。

Packagist / GitHub 自动发布时,谁在决定包内容? Packagist 拉取的是 Git tag 对应的 commit 的**干净快照**,等价于 git archive --format=zip HEAD。它依赖 Git 自身的导出机制,也就是 .gitattributes.gitignore 的组合行为。

  • .gitignore 只控制工作区文件是否被 Git 跟踪,不影响归档
  • .gitattributes 中的 export-ignore 才是归档时的“闸门”
  • 如果没写 .gitattributes,Git 默认会把所有 tracked 文件都打进 ZIP,包括 .git 目录下的东西(只要它被意外 track 过)

所以最稳妥的做法就是:删掉所有可能 track 过 .git 相关文件的痕迹,然后加一行 .git export-ignore.gitattributes

验证是否生效的最快方式 别等发布后才发现问题。本地就能测:

  • 确保已提交 .gitattributes
  • 运行:git archive --format=zip --output=test.zip HEAD
  • 解压 test.zip,检查里面有没有 .git/ 目录
  • 如果有,说明 .gitattributes 没生效(可能是路径不对、没提交、或用了 windows 换行符导致解析失败)

Git 归档不报错也不提示,它默默按规则执行——所以漏掉 .gitattributes 或写错格式,就会原样打包进去,连 warning 都没有。

text=ZqhQzanResources