跳到主要内容

Git 仓库迁移指南

什么时候用

当你想把整个仓库从一个代码托管平台迁移到另一个平台,并且希望保留分支、标签和其他 refs 时,最稳妥的方式通常是镜像迁移。

这类场景包括:

  • 从 Gitee 迁移到 GitHub
  • 从个人仓库迁移到组织仓库
  • 保留完整历史和标签,而不是只复制默认分支

先判断当前状态

  • 目标仓库最好是一个新建的空仓库,避免 --mirror 覆盖已有 refs。
  • 确认你对源仓库和目标仓库都具备读写权限。
  • 如果仓库使用了 Git LFS,大文件对象还需要额外迁移,不能只做一次普通 git push --mirror

推荐命令

完整迁移所有分支和标签

git clone --mirror git@gitee.com:username/repo-name.git repo-name.git
cd repo-name.git
git remote set-url origin git@github.com:username/repo-name.git
git push --mirror

这组命令会迁移所有 refs,而不只是当前分支。

常见场景

迁移完成后做基本检查

git remote -v
git for-each-ref --format='%(refname:short)' refs/heads refs/tags
git ls-remote --heads --tags origin

只想让当前工作副本改用新的远程仓库

如果你不是做“整仓镜像迁移”,只是要让已有工作目录切到新远程:

git remote set-url origin https://github.com/username/repo-name.git
git remote -v

仓库启用了 Git LFS

git push --mirror 只会同步 Git refs,不会自动帮你上传 LFS 大文件对象。此时建议在一个普通工作副本里额外执行:

git clone git@gitee.com:username/repo-name.git repo-name
cd repo-name
git lfs fetch --all
git remote add github git@github.com:username/repo-name.git
git lfs push --all github

如果你还没配置 Git LFS,可以先看 使用Git LFS克隆大文件

可选高级操作:改写历史提交邮箱

如果你的目的是让旧提交在 GitHub Contributions 中归属到新的邮箱,优先使用 git filter-repo,不要再把 git filter-branch 当首选。

在一个临时镜像副本里操作:

git filter-repo --commit-callback '
if commit.author_email == b"old-email@example.com":
commit.author_name = b"Your Name"
commit.author_email = b"github-email@example.com"
if commit.committer_email == b"old-email@example.com":
commit.committer_name = b"Your Name"
commit.committer_email = b"github-email@example.com"
'
git push --force --mirror

这会改写历史,只适合你明确知道后果、并且已经和协作者沟通过的场景。

风险与边界

  • git push --mirror 会让目标端 refs 与本地镜像完全一致,也会删除目标端多出来的 refs。
  • 如果目标仓库已经有 README、初始提交或默认标签,镜像推送可能会覆盖它们。
  • 历史改写类操作会改变提交哈希;只要别人已经基于旧历史开发,就必须提前协调。
  • git filter-branch 仍能工作,但现在已经属于 legacy 工具,不建议作为默认方案。