裸仓库是无工作区的Git仓库,初始化必须用git init --bare,仅用于接收推送和提供克隆,不可执行checkout/commit等操作。

裸仓库就是没工作区的仓库
裸仓库(bare repository)本质是把 .git 目录的内容直接放在仓库根目录下,不带任何可编辑的源文件。它不能执行 git checkout、git commit 等操作,只负责接收推送、提供克隆——典型用在远程服务器上做中央仓库。
别试图在裸仓库里改代码,也别用 git init 后手动删工作区来“模拟”,那容易漏文件、破坏引用。正确方式只有一种:初始化时就指定 --bare。
创建裸仓库必须加 --bare 参数
本地新建裸仓库:运行 git init --bare project.git,注意路径名习惯以 .git 结尾(不是强制,但 Git 工具链默认识别这种命名)。
常见错误:
- git init 后删掉所有非 .git 文件 → .git/index 和 .git/HEAD 可能残留状态,导致后续 git receive-pack 异常
- 用 git clone --bare 克隆已有仓库 → 得到的是镜像,不是空裸库,不适合当初始中央仓
- 把普通仓库整个重命名为 xxx.git → 没变内部结构,仍是非裸库,git push 到它会报错 refusing to update checked out branch
正确做法:
- 服务端首次建仓:直接
git init --bare /path/to/repo.git - 想从现有项目导出空裸库:先
git clone --bare,再清空repo.git/refs/heads/下的分支引用(慎用),或更稳妥地重新init --bare并用git push同步
推送代码到裸仓库要配 receive.denyCurrentBranch
裸仓库默认拒绝推送进当前分支(哪怕它没工作区),因为 Git 旧版本会检查 HEAD 是否指向某个已检出分支。虽然裸库没有工作区,但配置项仍生效。
现象:git push origin main 报错 remote: error: refusing to update checked out branch
解决方法(选其一):
- 在裸仓库里执行
git config receive.denyCurrentBranch ignore(最常用,适合 CI/CD 或只读同步场景) - 设为
updateInstead(Git 2.4+),允许推送直接更新引用,但需确保没其他进程依赖旧引用 - 不改配置,改用
git push --mirror或明确指定引用:git push origin main:refs/heads/main
注意:denyCurrentBranch = false 不合法,必须用 ignore 或 updateInstead。
裸仓库无法直接查看文件或运行 git status
裸仓库没有 worktree,所以 git log、git show 这类读取对象的操作可以,但 git status、git diff、git checkout 全部报错:fatal: this operation must be run in a work tree。
如果你需要临时看某次提交的代码,只能:
- 用
git archive --format=tar HEAD | tar -x解包快照 - 另起一个非裸克隆:
git clone /path/to/repo.git tmp-view && cd tmp-view - 用
git show HEAD:filename查单个文件内容
别给裸仓库装 IDE 插件或试图绑定编辑器——它不是开发环境,只是数据中转站。权限、钩子、备份策略才是重点。
裸仓库的“裸”字不是修饰词,是它的全部定义。一旦开始往里塞 .gitattributes 或写 post-receive 钩子,就得意识到:你正在维护一个无界面的服务组件,而不是本地项目副本。


















