git clone --mirror 是唯一能完整镜像远程分支的命令,它创建裸仓库,包含所有 refs/heads、refs/tags、refs/remotes 等引用,不带工作区,确保与源仓库完全一致。

git clone --mirror 是唯一能完整镜像远程分支的命令
普通 git clone 只拉取当前默认分支(通常是 master 或 main),所有其他远程分支在本地只是“可访问”,但不自动创建对应本地分支,更不会同步标签、reflog、甚至某些特殊引用(如 refs/pull/)。只有 git clone --mirror 会克隆整个裸仓库(bare repo),包含:refs/heads/、refs/tags/、refs/remotes/、refs/notes/ 全部引用,且不带工作区——这才是真正意义上的“镜像”。
常见错误现象:
– 用 git clone 后执行 git branch -r 看到一堆远程分支,就以为“都备份了”,其实只是远程引用快照,没保存提交对象本身;
– 用 git clone --bare 备份后,git push --mirror 到新地址失败,报错 ! [remote rejected] refs/notes/* (not a fast-forward) —— 因为 --bare 不等价于 --mirror,它不保证所有引用都被 fetch 下来。
-
git clone --mirror生成的是 bare 仓库,目录名以.git结尾(如myrepo.git),不可直接cd进去改代码 - 该命令默认 fetch 所有 refspec,包括 GitHub/GitLab 的 PR 引用(如果远程支持),但 Gitee 默认不暴露
refs/pull/,所以实际内容取决于远端配置 - Windows 下路径含空格或中文时,务必用双引号包裹 URL:
git clone --mirror "https://gitee.com/user/repo.git"
git push --mirror 必须推送到空仓库
这是最容易踩的坑:git push --mirror 不是“增量同步”,而是“全量覆盖”。它会强制删除目标仓库中所有已有分支、标签,并重写全部引用。如果目标仓库已存在内容,Git 会拒绝操作,报错类似:error: failed to push some refs to 'https://...',且不提示具体原因。
使用场景:
– 把本地镜像恢复到新建的 Gitee / GitHub 仓库(先在网页端创建空仓库,复制 SSH/HTTPS 地址);
– 在内网 Git 服务器间做灾备迁移;
– 不适用于日常“定时同步”,因为每次都会重置远端历史,破坏协作基础。
- 执行前确认目标仓库 100% 为空:打开网页,检查是否显示 “This repository is empty”
- 命令格式必须是
git push --mirror <new-remote-url></new-remote-url>,不能加origin别名;加了别名会尝试推到原origin,不是你想要的新地址 - 若目标仓库非空但你坚持要覆盖(例如测试环境),需先手动清空:进入目标仓库管理页 → Settings → Danger Zone → Delete this repository → 确认
恢复镜像后无法 checkout 分支?因为你没克隆出工作区
git clone --mirror 生成的是裸仓库,没有 .git 子目录,也没有工作文件。它只适合做备份或中转,不能直接开发。想恢复成可工作的本地仓库,得再走一次 git clone:
CNB 云原生构建平台的 Git 操作技能,支持代码克隆、提交、推送、分支管理、Merge Request 管理、流水线触发与结果读取。初次使用需收集用户的 Git 用户名和邮箱。
示例流程:
– 已有镜像目录:myrepo.git
– 想恢复成可编辑项目:git clone myrepo.git myrepo-work
– 进入:cd myrepo-work
– 查看所有分支:git branch -a(会列出 remotes/origin/xxx)
– 创建并切换本地分支:git checkout -b dev origin/dev
注意:
– 不要用 git clone --bare myrepo.git myrepo-work,这又得到一个裸库,还是不能改代码;
– 如果原镜像里有大量未推送的本地分支(即未被 origin 跟踪的分支),它们不会出现在 remotes/origin/ 下,需要进镜像目录手动查:git --git-dir=myrepo.git show-ref;
– 恢复后首次 git pull 可能失败,因为默认 upstream 未设置,应先 git branch --set-upstream-to=origin/main main。
git bundle 更适合离线传输,但不等于镜像
当无法直连远程仓库(比如内网机器无外网权限),git bundle 是替代方案,但它和 --mirror 有本质区别:bundle 是单个文件,只打包指定引用范围,不保留完整的引用命名空间。
关键差异:
– git bundle create all.bundle --all 会包含所有分支和标签,但不会包含 refs/remotes/ 或 refs/notes/;
– git clone all.bundle 得到的是普通仓库(带工作区),不是裸库;
– 无法用 git push --mirror 推送 bundle 文件,只能 git fetch 或 git pull 导入。
- 生成 bundle 前,先进入原仓库执行
git fetch --all,确保所有远程分支最新,否则--all只打包本地已知引用 - bundle 文件可校验完整性:
git bundle verify all.bundle - 想从 bundle 恢复特定分支(比如只恢复
prod):git clone all.bundle --branch prod --single-branch my-prod
真正镜像级备份的核心就两点:用 git clone --mirror 拉,用 git push --mirror 推。中间任何环节混用 --bare、普通 clone 或 git archive,都会漏掉分支、标签或引用元数据。尤其是 refs/replace/ 和 refs/worktree/ 这类高级引用,只有 --mirror 能保全。










