1. 迁移前先搞清楚:你要搬的到底是什么
接到"把旧仓库代码搬到新地址"这种活儿的时候,很多人的第一反应是 clone 一下、改个 remote、push 上去,半小时完事。我以前也这么干过,直到有次迁移完,测试同事拿着旧版本的 tag 去拉代码发现一片空白,release 流程直接卡住,我才意识到:代码迁移这件事,核心根本不在"代码"两个字上,而在"分支"和"tag"上。
1.1 代码迁移的本质:不是复制文件,是搬"引用"和"历史"
对于不了解 Git 内部机制的人来说,代码迁移听起来就是"把文件拷过去"。但实际上,Git 仓库的核心不是工作区里那一堆文件,而是 .git 目录下的对象数据库——每一次提交(commit)、每一个分支指针(refs/heads/)、每一个 tag 引用(refs/tags/),都保存在这里。你看到的文件只是某个 commit 的"快照投影"。
换句话说,真正的迁移对象是:
- 所有分支的完整提交历史,包括那些已经合并但还没删的分支;
- 所有 tag 引用,包括轻量 tag 和附注 tag;
- HEAD、远程跟踪分支(remote-tracking branches)等元数据。
如果只 clone 默认分支再 push,那么其他分支的提交对象虽然可能因为共享历史而存在于本地仓库,但新仓库里不会有对应的分支引用,等于这些分支"消失"了。这也是为什么我不建议用"复制文件"的思路去理解迁移。你可以把 Git 仓库想象成一个图书馆:分支和 tag 就是书架上的分类标签,commit 是书。你光把书搬过去,不把分类标签搬过去,图书馆就变成了一堆乱书。标题里的"将旧分支的 git 代码及 tag 全部迁移",关键词其实就是"全部"两个字——缺任何一个分支、任何一个 tag,都会让某个人在某一天突然拉不到代码。
1.2 迁移方案选型:镜像克隆、裸克隆、普通克隆怎么选
Git 提供了三种常见的克隆方式,很多人分不清它们的区别,这里直接给表格:
| 克隆方式 | 命令 | 包含内容 | 适用场景 |
|---|---|---|---|
| 普通克隆 | git clone <url> |
默认分支 + 远程跟踪分支 | 日常开发 |
| 裸克隆 | git clone --bare <url> |
所有分支、tag,无工作区 | 服务器端备份 |
| 镜像克隆 | git clone --mirror <url> |
所有分支、tag、远程跟踪配置 | 仓库整体迁移 |
这里重点推荐镜像克隆。它本质上是一个裸克隆,但会把源仓库的 remote 配置也一并复制过来,推送的时候用 git push --mirror 可以把你本地所有的 refs(包括远端分支、tag)原样推到新地址,是最接近"复制粘贴"的方案。
不过镜像克隆也有个前提:你得能通过 SSH 或者 HTTPS 完整拉取整个仓库。如果你的旧仓库非常大(几个 GB 甚至更大),或者网络条件不好,可以考虑 git clone --bare 配合 git fetch 增量同步,后面踩坑章节会细说。另外多说一句,如果旧仓库用了 Git LFS 管理大文件,迁移时记得确认 LFS 的对象也一并迁移了,否则新仓库里的大文件指针会变成一堆指向空对象的废链接。
1.3 动手前必须完成的盘点清单
在敲任何命令之前,我建议先花五分钟做一次盘点,确认三件事:
- 旧仓库有哪些分支:
git branch -a看本地和远程分支;git ls-remote --heads origin直接看服务器上的分支列表。 - 旧仓库有哪些 tag:
git tag -l看本地 tag;git ls-remote --tags origin看远端 tag。 - 旧仓库的提交量级:
git rev-list --all --count统计总提交数,用于迁移后的核对。
这一步看似多余,但非常关键。盘点清单就是迁移后的验收标准。我习惯把这些数据记下来,迁移完逐项比对,少一个分支、少一个 tag 都能立刻发现。别嫌麻烦,没有这份清单,出了问题你只能靠猜。尤其当旧仓库是团队里好几个人共同维护的,分支和 tag 的数量可能远超你的预期,光凭记忆根本靠不住。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心操作全流程:从旧仓库到新仓库的完整链路
盘点完之后就可以正式动
