直接改远程地址即可保留全部提交历史、分支、标签,最轻量安全的方式是用git remote set-url;若旧仓库将下线或需完整镜像,则用git clone --mirror加git push --mirror。

直接改远程地址就能保留全部提交历史、分支、标签,不需要重新 clone 或导出导入。
用 git remote set-url 切换远程仓库地址
这是最轻量、最安全的方式,适用于原仓库仍可访问、只是远程地址变了(比如从 GitHub 迁到 GitLab,或换了组织名)。
- 先确认当前远程名,通常是
origin:git remote -v - 把远程地址换成新 URL:
git remote set-url origin https://new-server.com/user/repo.git - 推所有分支和标签:
git push --all origin && git push --tags origin
注意:--all 只推本地已存在的分支,不会自动拉取远端新增分支;如果旧远程已不可达,git fetch 会失败,但不影响本地操作和推送新远程。
用 git clone --mirror 做完整镜像迁移
当旧仓库即将下线、或需要确保所有引用(包括 reflog、带权限的私有分支)都被复制时,镜像克隆更可靠。它会拉取所有分支、标签、甚至 refs/pull/ 等 GitHub 特有引用(取决于服务端支持)。
- 在空目录中执行:
git clone --mirror https://old-server.com/user/repo.git - 进入克隆出的 bare 仓库:
cd repo.git - 添加新远程:
git remote set-url --push origin https://new-server.com/user/repo.git - 全量推送:
git push --mirror origin
--mirror 会强制覆盖目标远程的所有引用,包括删除对方已存在但本地没有的分支——慎用于已有协作的仓库。另外,GitHub/GitLab 的 fork 关系、issue、CI 配置等不会被镜像,这些需手动处理。
遇到 non-fast-forward 拒绝推送?检查是否漏了 --force 或 --mirror
新远程如果已有内容(比如初始化过空仓库),Git 默认拒绝覆盖历史。这不是错误,是保护机制。
- 如果是首次推送且确定要清空目标远程:加
--force(仅对单分支)或用--mirror(对整个裸库) - 别对普通工作仓库用
git push --force --all,容易误删他人分支;优先走--mirror+ bare 仓库流程 - 某些托管平台(如 GitLab)默认禁用强制推送,需在项目设置里开启 “Allow force push”
另外,git push --tags 不会推送附注标签(annotated tag)以外的引用,如果旧仓库用了轻量标签(lightweight tag),得用 git push --force --tags 或配合 --mirror 才能确保不丢。
真正容易被忽略的是:迁移后本地配置里的 remote.origin.url 虽然改了,但 remote.origin.pushurl 可能还指向旧地址——用 git config --get remote.origin.pushurl 检查,必要时一并更新。










