.gitignore 中的 /vendor 无效是因为 Git 已追踪该目录;需先执行 git rm -r --cached vendor 并提交,再确保规则为 /vendor/。

为什么 .gitignore 里加 /vendor 还是提交了?
常见现象是:明明在项目根目录的 .gitignore 里写了 /vendor,但 git status 仍显示一堆 vendor/ 下的文件,甚至能 git add 成功。这是因为 Git 已经追踪过这些文件——.gitignore 只对「未被追踪」的文件生效,对已 git add 过的目录完全无效。
实操建议:
- 先确认是否已被追踪:
git ls-files --error-unmatch vendor/autoload.php 2>/dev/null && echo "已追踪" - 如果输出
已追踪,必须手动取消追踪:git rm -r --cached vendor - 执行后记得提交这个变更:
git commit -m "remove vendor from git tracking" - 确保
.gitignore中该行是/vendor/(结尾斜杠更安全,避免匹配到myvendor这类名字)
Composer install 后 vendor 被意外修改怎么办?
典型场景:CI 构建或团队协作中,有人本地运行了 composer install 或 composer update,结果生成了新文件(如 vendor/bin/xxx 符号链接)或修改了 vendor/composer/installed.json 权限,导致 Git 误报变更。
原因在于 Composer 默认行为会写入可执行权限、生成二进制软链,而这些在不同系统上表现不一致(尤其 Windows + WSL 混用时)。
实操建议:
- 统一关闭自动创建二进制链接:
"config": { "bin-dir": "bin/", "bin-compat": "full" }改为"bin-compat": "system"或直接删掉(默认值已是system) - 禁止写入权限位(关键):在
composer.json加"config": { "discard-changes": true },防止本地修改被意外暂存 - CI 环境强制使用
--no-scripts --no-autoloader,减少副作用
git check-ignore -v vendor/autoload.php 返回空,说明什么?
这个命令没输出,不代表文件被忽略——它只检查「当前路径下是否匹配某条 .gitignore 规则」。如果返回空,常见原因是:
-
vendor/目录本身已被 Git 追踪(即上面说的「已缓存」状态),此时check-ignore不会报告,因为它根本不在忽略逻辑链路上 -
.gitignore写在子目录里(比如src/.gitignore),对根目录vendor/无效 - 规则写成了
vendor(无斜杠),可能被myvendor/或app/vendor/误匹配,但实际没生效
正确验证方式:git status --ignored 看 vendor/ 是否出现在 Ignored files 区域;或者删掉整个 vendor/,再 git status,如果不再出现,说明忽略已生效。
团队协作中如何防止新人误提 vendor?
光靠文档或口头提醒没用。真正起效的是机制约束:
- 在项目根目录放一个
.gitattributes文件,内容为:vendor/** export-ignore(配合git archive使用,虽不防 commit,但能降低发布包污染风险) - CI 流水线加检查:
git ls-files vendor/ | head -n1 | grep -q "." && echo "ERROR: vendor found in index" && exit 1 || exit 0 - 用 Husky + lint-staged 做 pre-commit 钩子(需 Node 环境):
git diff --cached --name-only | grep "^vendor/" && echo "Don't commit vendor!" && exit 1 - 最省事但有效的一招:把
vendor/加进.git/info/exclude(本地忽略,不影响他人,适合临时调试)
真正难处理的不是规则怎么写,而是已有历史提交里混进了 vendor。那种情况就得用 git filter-repo 彻底清理,代价高、影响大,越早预防越好。










