必须加 --keep-vcs 才能保留 .git 目录,否则 Composer 默认强制删除,导致提交历史、远程配置和分支状态丢失;目标目录已有 .git 时会报错退出,需手动清理或换路径。

composer create-project 保留 .git 必须加 --keep-vcs
不加 --keep-vcs,Composer 会直接 rm -rf .git,新项目彻底丢失原始提交历史、远程配置和分支状态。它不是“默认保留再清理”,而是“默认强制清空”。只有显式传参才跳过这步删除逻辑。
常见错误现象:执行 composer create-project laravel/laravel myapp 后进目录跑 git status 报错 “Not a git repository”,或 git remote -v 为空——说明 Git 元数据已被抹除。
使用场景包括:
- 基于开源模板快速初始化私有项目,并需后续
git diff upstream/main追踪上游变更 - 团队内部维护带 CI 脚本和定制钩子的模板库,每个新项目都应继承完整 Git 上下文
- CI 中动态生成骨架,要求产物可追溯到模板仓库某次 tag
目标目录已存在 .git 时会直接报错退出
--keep-vcs 不覆盖、不合并、不提示。如果目标路径下已有 .git 目录(哪怕只是空文件夹),Composer 会立即中止并输出类似 Project directory myapp/ is not empty and has a .git directory 的错误。
必须手动处理:
- 删掉整个目标目录,或换新路径重试
- 若想保留已有修改,先
git stash或备份再清空 - 别指望
--force或--no-interaction能绕过这个检查
Windows 下还可能因权限异常导致后续 git status 失败,建议初始化后补一句 git config --local core.autocrlf true。
保留 VCS ≠ 自动同步子模块或更新远程
--keep-vcs 只保留原始 .git/ 目录结构、HEAD、config、refs/ 等元数据,不执行任何 Git 操作。
容易被忽略的副作用:
- 原始仓库若有
.gitmodules,不会自动运行git submodule update --init,得手动补 - 如果源仓库的
origin是私有地址(如git@gitlab.example.com:team/pkg.git),而当前机器没配 SSH key,后续git pull会失败 - 某些包的
post-create-project-cmd脚本仍会运行,可能重写.git/config,覆盖你刚保留的 remote
缓存迁移与 VCS 无关,别混用 vcs/ 和 files/ 目录
Composer 的 cache/vcs/ 存的是裸仓库快照(用于 --prefer-source),而 cache/files/ 存的是 ZIP 包(用于 --prefer-dist)。--keep-vcs 完全不碰这两处缓存。
如果你在离线环境迁移开发环境,要同步的是:
-
vendor/目录(最稳) - 或完整打包
~/.composer/cache/files/(必须确保所有子依赖 ZIP 都已下载) - 但
cache/vcs/可删可不删——它只影响下次--prefer-source行为,跟--keep-vcs无任何交集
真正容易出问题的地方是:以为保留了 .git 就等于“项目可复现”,却忽略了 composer.lock 里记录的 dist URL 和哈希值仍指向在线资源。离线时若没提前缓存好 ZIP,composer install 依然会卡住。











