git clone --mirror 完整迁移仓库的全流程

git clone --mirror 是迁移 Git 仓库最彻底、最可靠的方式,它会完整复制原仓库的所有引用(分支、标签、PR/MR 引用、notes 等),保证目标仓库与原仓库在 Git 对象层面完全一致。

以下是完整迁移流程,按场景分类:


一、核心原理

--mirror 等价于 --bare + 所有引用映射,它会:

  • 克隆所有分支(包括远程追踪分支)
  • 克隆所有标签
  • 克隆所有 Git 引用(如 refs/pull/*/headrefs/notes/* 等)
  • 保留完整的 reflog 和配置

二、标准迁移流程(通用)

步骤 1:镜像克隆原仓库

bash 复制代码
# 创建裸镜像
git clone --mirror https://github.com/old-org/old-repo.git
cd old-repo.git

步骤 2:配置目标仓库地址

bash 复制代码
# 设置目标仓库为新的 remote
git remote set-url origin https://github.com/new-org/new-repo.git

步骤 3:推送所有引用到目标仓库

bash 复制代码
# 推送所有分支、标签、引用
git push --mirror

注意 :如果目标仓库已存在内容,--mirror 推送会强制覆盖,确保目标仓库为空或你确实要覆盖。

步骤 4:清理本地镜像(可选)

bash 复制代码
cd ..
rm -rf old-repo.git

三、完整迁移清单(生产环境推荐)

1. 迁移前准备

bash 复制代码
# 1. 确认原仓库完整性
git clone --mirror https://github.com/old-org/old-repo.git
cd old-repo.git

# 2. 检查仓库大小和引用数量
git count-objects -vH
git show-ref | wc -l

# 3. 验证所有分支和标签
git branch -a
git tag -l

# 4. 检查是否有 Git LFS 文件
git lfs ls-files 2>/dev/null || echo "No LFS detected"

2. 创建目标空仓库

在 GitHub/GitLab/Gitea 等平台创建一个空仓库(不要初始化 README、License 或 .gitignore)。

3. 执行迁移推送

bash 复制代码
# 设置目标地址
git remote set-url origin https://github.com/new-org/new-repo.git

# 推送所有引用(分支 + 标签 + 其他 refs)
git push --mirror

# 如果目标仓库有保护规则限制强制推送,可能需要先临时关闭

4. 迁移 Git LFS(如有)

bash 复制代码
# 如果原仓库使用了 Git LFS,需要单独迁移 LFS 对象
git lfs fetch --all
git lfs push --all origin

5. 验证迁移完整性

bash 复制代码
# 在新机器上克隆目标仓库验证
cd /tmp
git clone https://github.com/new-org/new-repo.git
cd new-repo

# 对比提交数量
git rev-list --all --count

# 对比标签
git tag -l | sort

# 对比分支
git branch -a

四、不同平台迁移的特殊处理

GitHub → GitHub(含 PR 引用)

GitHub 的 Pull Request 引用存储在 refs/pull/*/headrefs/pull/*/merge--mirror 会保留这些引用,但新 GitHub 仓库不会自动重建 PR 记录(PR 是平台元数据,不是 Git 数据)。

bash 复制代码
# 镜像克隆会拉取 PR 引用,但新仓库中这些只是普通引用
git clone --mirror https://github.com/old-org/old-repo.git
git push --mirror https://github.com/new-org/new-repo.git

PR 历史、Issue、Wiki、Actions 记录等属于平台数据,需通过 API 或平台自带迁移工具迁移。

GitLab → GitLab(含 MR 引用)

GitLab 的 MR 引用在 refs/merge-requests/*。同样,--mirror 会保留引用但不会自动重建 MR 记录

自建 Git 服务器 → 新服务器

bash 复制代码
# 直接在服务器上操作(更快)
cd /var/git/old-repo.git
git push --mirror ssh://new-server/var/git/new-repo.git

五、高级:保留原仓库所有配置

bash 复制代码
git clone --mirror https://github.com/old-org/old-repo.git
cd old-repo.git

# 查看原仓库 remote 配置
cat config

# 修改 origin URL 指向新仓库
git remote set-url origin https://github.com/new-org/new-repo.git

# 如果需要保留其他 remote(如 upstream)
git remote -v

# 推送所有引用
git push --mirror

六、常见问题

问题 原因 解决
! [remote rejected] ... 目标仓库有保护分支 临时关闭分支保护
! [rejected] ... (fetch first) 目标仓库非空 创建空仓库或先清空
LFS 文件缺失 未迁移 LFS 对象 执行 git lfs push --all
PR/MR 历史丢失 PR 是平台数据 使用平台 API 迁移
仓库体积异常大 包含大量垃圾对象 原仓库先 git gc --aggressive

七、一键迁移脚本

bash 复制代码
#!/bin/bash
set -e

OLD_URL="https://github.com/old-org/old-repo.git"
NEW_URL="https://github.com/new-org/new-repo.git"
REPO_NAME="old-repo"

# 1. 镜像克隆
git clone --mirror "$OLD_URL" "${REPO_NAME}.git"
cd "${REPO_NAME}.git"

# 2. 检查 LFS
if git lfs ls-files 2>/dev/null | head -1; then
    echo "检测到 Git LFS,正在迁移..."
    git lfs fetch --all
fi

# 3. 设置新地址并推送
git remote set-url origin "$NEW_URL"
git push --mirror

# 4. 推送 LFS(如有)
if command -v git-lfs &> /dev/null && [ -d "lfs" ]; then
    git lfs push --all origin
fi

# 5. 清理
cd ..
rm -rf "${REPO_NAME}.git"

echo "迁移完成: $NEW_URL"

八、迁移后必做检查

  1. 提交历史git log --oneline --all --graph | head -20
  2. 标签完整性git tag -l | wc -l 对比原仓库
  3. 分支完整性git branch -a
  4. 大文件/LFS:检查仓库体积是否合理
  5. CI/CD 配置:更新 webhook、部署密钥、CI 变量
  6. Issue/PR 链接 :旧仓库中的 #123 链接会失效,需平台级迁移

相关推荐
wdfk_prog9 小时前
GitHub push 失败:如何扫描并清理 Git 历史中的大文件
git·elasticsearch·github
大明二代11 小时前
使用 Traefik、cert-manager 和 DNS-01 为内网 Kubernetes 服务配置 HTTPS
git·kubernetes·flux
小芒果_0112 小时前
git常用命令速查
大数据·git·elasticsearch
2501_9304724414 小时前
腾讯云助手规范化Git提交记录
git·elasticsearch·腾讯云
风尘小子1 天前
git的.gitignore文件中文件和目录配置
git
Tanner_SL1 天前
Linux笔记之GIT常用命令
linux·git
醉颜凉1 天前
Jenkins与Git集成完全指南:从基础配置到自动触发构建
运维·git·jenkins
樱花落木兰1 天前
Git 超全零基础教程|三区原理、全套命令、分支协作、冲突解决、IDEA 集成(面试必备)
ide·git·json·github
云和数据.ChenGuang1 天前
git revert回退问题
java·服务器·人工智能·git·fastapi·强化学习
伞伞悦读1 天前
【第12期】Windows 开发环境备份与恢复:软件、环境变量、Git、conda 和 Docker 卷完整方案
git·docker·conda