GitLab 代码仓库迁移与同步最佳实践

关键词:GitLab,Repository Mirror,Push Mirror,跨实例同步,CI/CD

背景

有两个独立的 GitLab 实例:

  • 新仓库(主开发地址):https://gitlab.new.xyz/group/project
  • 旧仓库(历史地址):http://gitlab.old.xyz/group/project

未来所有开发和维护都在新仓库进行,但旧仓库因为历史问题还需要继续使用(如旧流水线、旧部署脚本仍指向旧地址)。

起初不知道有 Mirror 这功能,直接配置 gitlab.yml 来执行,发现存在很多不方便的地方,比如两个仓库的 gitlab runner 不同,仓库配置使用的 Gitlab 环境变量不同,一旦同步,gitlab pipeline 在旧的仓库也会触发,引起麻烦。

目标:新仓库 master 分支的每次提交,自动同步到旧仓库,不需要人工干预

扩宽知识面,充分使用已有的完善的工具,避免重复造轮子、绕圈子,也是一个很好的习惯。

在工作中,如何实现功能、做成事情不是特别重要,只要结果目的达到。

但是如果过程能善假于物,借助成熟的方案,节省更多时间和精力的方案更值得推荐。


方案选型

有三种常见方案:

方案 触发时机 运维成本 前提条件
GitLab Push Mirror(内置) push 后即触发 极低 源实例支持 Mirror 功能
CI/CD Pipeline 脚本推送 push 后即触发 Runner 可访问目标实例
定时 cron 脚本 分钟级延迟 有中间跳板机

最终选择 GitLab 内置的 Push Mirror,原因是配置一次之后完全托管,不需要维护额外脚本,也不依赖 Runner 的网络环境。


原理简介

GitLab 的 Repository Mirroring 分两种方向:

  • Pull Mirror:从远端拉取到本仓库(目标仓库拉取源仓库)
  • Push Mirror:本仓库有新提交时,主动推送到远端(源仓库推送到目标仓库)

本次使用 Push Mirror。每次向源仓库 push 代码,GitLab 会在后台自动执行一次 git push 到配置好的镜像地址,认证通过 Access Token 完成。

官方文档参考:Repository mirroring | GitLab Docs


配置步骤

第一步,获取原 GitLab 上的账号信息

方向一:

如果是旧版本的 Gitlab,可以直接先尝试使用登录的账号密码

方向二:

通常情况下,登录 gitlab.old.xyz,进入目标项目,依次打开:

  • Settings → Access Tokens
  • 创建一个 Project Access Token,权限勾选 write_repository,记录生成的 token 值
  • 也可以使用 Personal Access Token,效果相同。

第二步,在源 GitLab 上配置 Push Mirror

方向一:

使用账号密码,类似: http://username:password@gitlab.old.xyz/group/project.git,其他步骤同下。

方向二:

登录 gitlab.new.xyz,进入源项目,依次打开:

Settings → Repository → Mirroring repositories

点击 Add new,填写:

  • Git repository URL,例如 http://<token_name>:<token>@gitlab.old.xyz/group/project.git
  • Authentication method - Username 和 Password(用于登录旧 Gitlab 的账号密码)
  • 选择性勾选 Keep divergent refs 和 Mirror only protected branches

最后点击 mirror repository,GitLab 会立即触发一次同步,可以在列表里看到同步状态。

如果出现报错,可以看到 Error 信息,再根据报错排查问题。

第三步,验证

在源仓库随便推一个提交,然后去旧仓库刷新,确认提交已经同步过来。

同步一般在几秒到一分钟内完成,延迟取决于两个实例之间的网络情况。


旧仓库的后续处理

旧仓库变成纯镜像仓库后,不再需要任何协作功能,建议做以下关闭操作,避免有人误操作在旧仓库提交代码:

进入旧仓库:Settings → General → Visibility, project features, permissions

关闭以下功能:

  • Merge requests,关闭后 MR 入口消失,无法再创建新的合并请求
  • Issues(可选),旧仓库不需要 issue 跟踪

小结

整体方案很简单:源仓库配 Push Mirror,目标仓库关掉协作功能,一次配置,长期生效。

唯一需要注意的是,如果使用 token,那么 Access Token 的有效期,GitLab 默认 Token 可以设置过期时间,建议设置一个较长的有效期或者不过期,避免某天同步静默失败。