一. why
项目需要用到github第三方库, 但是直接依赖github是有问题, 第一有墙容易失败, 第二github不可控(某天中美打架人家删库)等, 所以需要在gitlab映射一份github的库.
二. 方案选择
2.1 拷贝
先本地git clone github, 然后将特定分支(tag)代码拷贝出来, 推送到gitlab
优: 简单
劣: 丢失github本身的信息
2.2 同步
先本地git clone github, 然后添加gitlab的源, 并将github信息推送到gitlab
优: 保持和github同步
劣: 保留所有信息, 库会大一点(冗余)
综合来讲: 还是第二种方案更好点
三. 实践
- clone 源码
git clone https://github.com/**.git - 查看源
git remote -v
git remote -v
origin https://github.com/google/double-conversion.git (fetch)
origin https://github.com/google/double-conversion.git (push)
- 修改名称
git remote rename origin github - 再次查看, 发现源从origin换成了github
git remote -v
github https://github.com/boostorg/boost.git (fetch)
github https://github.com/boostorg/boost.git (push)
- 添加gitlab源
git remote add origin http://gitlab.**.git - 再次查看
git remote -v
github https://github.com/boostorg/boost.git (fetch)
github https://github.com/boostorg/boost.git (push)
origin http://gitlab.**.git (fetch)
origin http://gitlab.**.git (push)
- 推送到gitlab
git push origin master - 同步tag
git push origin --tags - done
去gitlab查看信息, 和github一致, 分支和tag都相同.
四. 踩坑(针对 GitLab 实际情况)
按文章前面的方案直推到 GitLab 时, 容易碰到两个文章没有提到的坑.
4.1 GitLab 创建仓库时勾了 "Initialize with README" → 推送被拒
现象
! [rejected] master -> master (fetch first)
hint: Updates were rejected because the remote contains work that you do not have locally.
原因: GitLab 创建仓库时若勾选 Initialize repository with a README, 远端会有一个本地没有的初始 commit, 非快进推送被拒.
解决: 镜像同步要的就是 "GitLab 完全等于 GitHub", 直接 force push 覆盖:
git push -f origin master
或者建仓库时干脆别勾 README, 文章原步骤就能直接走通.
4.2 master 默认是 protected branch → 连 force push 都会被拦
现象
remote: GitLab: You are not allowed to force push code to a protected branch on this project.
! [remote rejected] master -> master (pre-receive hook declined)
原因: GitLab 默认把 master / main 设为 protected branch, 即使是 Maintainer 也不允许 force push.
解决: 进入仓库 Settings → Repository → Protected Branches, 对 master 点 Unprotect 移除保护后再推.
镜像仓库建议 永久不保护 master: 上游偶尔会 rebase / force-update tag, 镜像必须能跟随, 一直保护反而碍事.
五. 后续上游同步
GitHub 上有新提交后, 把改动同步到 GitLab 镜像:
git fetch github
git checkout master
git merge --ff-only github/master
git push origin master
git push origin --tags
如果上游 rebase 了导致非 fast-forward, 末尾两行换成:
git push -f origin master
git push -f origin --tags