从 GitLab 搬仓库到 AngusGit:公开项目直接导入,私有和内部项目推送

简介: 内网 GitLab 上的公开项目可以用「导入仓库」搬进 AngusGit,但只会带上默认分支当时的文件,已经导入的 xlliu/hello-world-import 就是这样,只有 main;内部和私有项目则要先 clone --bare,再推到按子组路径规则建好的空仓库。

这篇讲内网 GitLab 上的公开、内部和私有项目,分别怎么搬到 AngusGit。看完你可以按可见性(谁能看到仓库)选择导入或推送,把多层子组定成「团队/仓库名」,再用 git clone --bare 加 git push --all 和 --tags 推进空仓库,并用 git ls-remote 对比两边是否一致。

先登录 AngusGit。公开项目在侧栏 仓库 点 导入仓库。仓库 URL 填项目页 克隆 里的 HTTPS 地址,不要填 SSH。所有者 选团队,仓库名称 按下一节的路径规则填,名称只能用中文、字母、数字、连字符和下划线。只给内部看时打开 设为私有仓库。这三项填完,开始导入 才能点。

推送前在 我的 → 访问令牌 点 生成新令牌,密码验证 填登录密码,勾 git:write,仓库权限 WRITE,生成后马上复制。用户名填登录名,密码填令牌。先手动成功推一个仓库,在系统凭据窗口里保存,后面的批量脚本才不会每行都问密码。改用 SSH 时,没有 ~/.ssh/id_ed25519.pub 就执行 ssh-keygen -t ed25519 -C "you@example.com",把 cat ~/.ssh/id_ed25519.pub 的那一行登记到 我的 → SSH密钥。用户名是 git,端口是 2222。

下文的 GitLab 地址用 https://gitlab.example.com/platform/backend/order-service.git 举例:platform 是群组,backend 是子组,order-service 是项目,换成你自己的路径即可。公开仓库导入长什么样,看已经导入的 xlliu/hello-world-import:只有 main 和一条提交。整个团队怎么双跑和回滚,见文末的 GitLab 迁移清单一文。

1. 先看 GitLab 项目的可见性

项目页名称旁边、或 设置 → 通用 → 可见性 里,三种的差别如下:

GitLab 可见性 不登录能读吗 在 AngusGit 上用哪条路
公开 能 只要当前代码:导入仓库。要保留历史:推送
内部 不能,要登录 GitLab 推送
私有 不能,要是项目成员 推送

判断方法很简单:打开浏览器的无痕窗口,不登录访问项目页,能看到代码才能用导入。

公开项目可以导入或推送,内部和私有只能推送

2. 公开项目:直接导入

侧栏点 仓库 → 右上角 导入仓库,仓库 URL 填 GitLab 项目页 克隆 里的 HTTPS 地址,不要填 SSH 地址,因为 AngusGit 服务器上没有你的 SSH 密钥。同一张表单导入公开仓库的结果,见 GitHub 上的 Hello-World 导入成的 xlliu/hello-world-import。

真正去拉代码的是 AngusGit 服务器,它要能访问那台 GitLab。导入只带默认分支当时的文件;源分支叫 master 时,AngusGit 上的分支名仍是 main。表单按开头填写:仓库 URL、所有者、仓库名称,需要时打开 设为私有仓库。

3. 定好路径怎么对应

GitLab 的项目可以放在多层群组下面,例如 platform/backend/order-service。AngusGit 的仓库地址只有两级:所有者(个人或团队)加仓库名,所以整批项目都要按同一条规则对应过去。常见的两种对应方式:

GitLab 路径 方式一:一级群组对应团队 方式二:子组并进仓库名
platform/backend/order-service platform/order-service platform/backend-order-service
platform/frontend/order-web platform/order-web platform/frontend-order-web

方式一的地址短,但不同子组下有同名项目时会撞名。方式二不会撞名,地址稍长。拿不准就用方式二。

还要检查项目名里有没有点号。AngusGit 的仓库名只能用中文、字母、数字、连字符和下划线,点号会被去掉,例如 docs.site 要提前改成 docs-site。

4. 私有和内部项目:克隆后推送

  1. 在 AngusGit 建团队和空仓库

    按第 3 节定好的规则,先在 AngusGit 建好团队,再在团队下建同名的空仓库。新建仓库时,添加 README 文件、添加 .gitignore、选择许可证 三项都不要勾选。任何一项勾上,仓库就不再是空的,推送时会被拒绝。

  2. 从 GitLab 完整克隆

    用你自己的 GitLab 账号克隆。GitLab 开了双因素认证时,HTTPS 的密码一栏要填 GitLab 的个人访问令牌,权限勾选 read_repository 就够了。--bare 会把 GitLab 上的所有分支和标签都拉下来,不生成工作区。

  3. 主分支叫 master 时先改名

    AngusGit 新建的空仓库默认分支是 main。GitLab 项目的主分支叫 master 时,先在本地改名;已经是 main 就跳过。改名之后,团队成员的本地习惯、GitLab CI 里写死的分支名,都要跟着改成 main。

  4. 推送所有分支和标签

    第一行推所有分支,第二行推所有标签。HTTPS 的用户名填 AngusGit 登录名,密码填一把勾了 git:write 的访问令牌。用 SSH 地址也可以。

对应的完整命令如下。gitlab.example.com 和 platform/backend-order-service 都要换成你的地址,并先建成空仓库。主分支已经叫 main 时,跳过 git branch -m。推送用的 HTTPS 地址换成你的空仓库;私有仓库克隆时会要访问令牌,按开头生成 git:write 令牌,不要把令牌写进文章或截图。

git clone --bare https://gitlab.example.com/platform/backend/order-service.git
cd order-service.git
git branch -m master main
git push https://git.anguskit.com/platform/backend-order-service.git --all
git push https://git.anguskit.com/platform/backend-order-service.git --tags

--bare 得到的是裸仓库:只存 Git 数据,没有可编辑的工作区,正好用来原样转推。为什么不用 --mirror?--mirror 会把远程的所有引用都拉下来,包括 GitLab 为每条合并请求保存的 refs/merge-requests/*。之后再 git push --mirror,这些引用会原样出现在 AngusGit 仓库里,既没用,还会干扰分支列表和统计。--bare 配合 --all 和 --tags,只推分支和标签,正好是需要的部分。

5. 一次搬一批

项目多时,把对应关系写进一个文本文件,每行两列:GitLab 路径和 AngusGit 上的「所有者/仓库名」。AngusGit 上的空仓库要先按第 4 节第一步建好。

platform/backend/order-service platform/backend-order-service
platform/frontend/order-web platform/frontend-order-web

保存为 repos.txt,然后执行:

while read -r src dst; do
  git clone --bare "https://gitlab.example.com/${src}.git" tmp.git || continue
  git -C tmp.git branch -m master main 2>/dev/null
  git -C tmp.git push "https://git.anguskit.com/${dst}.git" --all
  git -C tmp.git push "https://git.anguskit.com/${dst}.git" --tags
  rm -rf tmp.git
done < repos.txt

脚本逐行克隆、改名、推送,然后删掉本地副本。运行之前,先按开头手动搬一个仓库,让系统的凭据管理器记住 GitLab 和 AngusGit 两边的令牌;否则脚本每一行都会停下来问密码。

AngusGit 的 批量导入 也能一次处理很多地址,但它和单个导入一样只读公开项目、只带当前文件,而且导入的仓库全部是公开的。内网 GitLab 的项目,用上面的脚本更合适。

6. 验收:两边的分支和标签要一模一样

每个仓库推完,对比两边的分支和标签。下面的命令分别列出 GitLab 和 AngusGit 上所有分支、标签指向的提交,再逐行比较:

diff \
  <(git ls-remote --heads --tags https://gitlab.example.com/platform/backend/order-service.git | sort) \
  <(git ls-remote --heads --tags https://git.anguskit.com/platform/backend-order-service.git | sort)

没有任何输出,说明两边一致。如果第 4 节把 master 改成了 main,会看到这一对差异,属于预期;除此之外的差异,说明有分支或标签没推上去,重新执行一次推送即可。

最后打开 AngusGit 上的仓库,在 分支 页签核对数量,在提交记录里看作者和时间是否和 GitLab 一致。

导入只有一个分支;推送才应该和源仓库的分支、标签一致

上图左边是导入的结果,不是一次完整推送;推送验收要以 git ls-remote 没有意外差异为准。master 改成 main 时,这一对名字对不上是预期的。

7. 哪些东西不在 Git 仓库里

推送只搬 Git 仓库里的内容。下面这些要在 AngusGit 上重新配置:

GitLab 上的内容 是否随 git push 过去 在 AngusGit 上怎么处理
项目成员和角色 否 把成员加进 AngusGit 的团队,或在仓库 设置 → 访问 里加协作者
受保护分支 否 在仓库 设置 → 分支保护 里重新建规则
合并请求、议题、Wiki 否 进行中的合并请求在 GitLab 上合并或关闭后再搬
.gitlab-ci.yml 文件过去但不会运行 在控制台用 导入 GitLab CI 转成 .anguscicd.yaml
Webhook 否 在仓库 设置 → Webhooks 里重新添加

8. 出错时

你看到的 原因 怎么处理
导入时提示 源仓库URL「…」无效或无法正常访问 项目是内部或私有的;填的是 SSH 地址;或者 AngusGit 服务器连不上 GitLab 内部和私有项目按第 4 节推送。公开项目确认填的是 HTTPS 地址,并在 AngusGit 服务器上执行 git ls-remote <地址> 检查网络
克隆 GitLab 时 HTTP Basic: Access denied GitLab 开了双因素认证,或者密码不对 密码一栏改填 GitLab 个人访问令牌
推送时 ! [rejected] main -> main (fetch first) AngusGit 上的仓库不是空的 删掉重建一个三项都不勾的空仓库
推送时 repository '…' not found AngusGit 上还没建这个仓库,或者所有者、仓库名和第 3 节的对应规则不一致 先建空仓库,再核对地址里的团队名和仓库名
验收时只有部分标签对不上 第二行 --tags 没执行,或者中途断开 重新执行一次 git push <地址> --tags

常见问题

GitLab 上的项目以后还会更新,能先搬一份,过段时间再补吗?

能。最简单的做法是再执行一遍第 4 节:重新 git clone --bare,需要时改名,再推送。AngusGit 上已有的提交不会重复,推送只会把 GitLab 上新增的提交补过去。前提是这段时间里没有人直接往 AngusGit 推代码,否则两边分叉,推送会被拒绝。正式切换前反复同步、最后冻结 GitLab 再同步一次的做法,见 GitLab 迁移清单一文。

能保留 GitLab 合并请求里的评审记录吗?

不能。评审记录存在 GitLab 的数据库里,不在 Git 仓库中。需要留档时,在 GitLab 上导出或截图保存。

项目用了 Git LFS 怎么办?

AngusGit 不支持 Git LFS。推过去之后,LFS 管理的大文件只剩指针文件。这类文件要改成普通文件提交,或者放到制品库里。

GitLab 的子模块地址要改吗?

要。仓库里的 .gitmodules 如果写的是 GitLab 地址,子模块仍然会从 GitLab 拉。等子模块对应的仓库也搬到 AngusGit 之后,把 .gitmodules 里的地址改成 AngusGit 地址,再提交一次。

小结

从 GitLab 搬仓库,先看项目的可见性。公开项目可以直接用 导入仓库,但只带当前文件;内部和私有项目,以及要保留历史的项目,在 AngusGit 建空仓库,git clone --bare 之后用 --all 和 --tags 推送。子组路径提前定好对应规则,项目名里的点号提前改掉。一批项目用一个对应关系文件加循环脚本处理。每个仓库推完,用 git ls-remote --heads --tags 对比两边,一致才算搬完。

结论: GitLab 内部和私有仓库(以及需保留历史的仓库)应先将多层子组映射为「团队/仓库名」,再用 git clone --bare 加 git push --all / --tags 推入空仓库,并用 git ls-remote 对比验收。

相关文章
|
云安全 安全 网络安全
|
7天前
|
JavaScript 安全 前端开发
Nodejs Brotli decoder 代码执行漏洞 (CVE-2026-111497)10629
Node.js发布安全更新修复Brotli解码器高危RCE漏洞(CVE-2026-111497),建议受影响版本用户立即升级。
2009 1
|
14天前
|
JSON 程序员 数据格式
最新版Notepad++下载、安装、配置保姆级教程(附官网安装包)
Notepad++ 是一款免费开源、轻量快速的 Windows 文本编辑器,支持多标签、语法高亮、代码折叠与宏录制,体积小、启动快、资源占用低,兼容 x64/x32/ARM 架构,是程序员和文字工作者的高效利器。
3200 0
|
13天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
2295 44
|
10天前
|
Web App开发 人工智能 前端开发
2026 年 AI 浏览器怎么选?Ego Lite、Tabbit、Chrome DevTools MCP 深度对比,开发者到底该用哪个?
2026年AI浏览器选型指南:Ego Lite专注多Agent协同(Mac优先),Tabbit国产首选,原生支持Windows与Codex控制;Chrome DevTools MCP非浏览器而是开发者利器,深度集成Console/Network/Performance调试能力,让AI真正“看懂并验证”前端代码。
1434 3
|
7天前
|
安全 应用服务中间件 Go
PHP2Shell 漏洞拆解:WordPress 与 nginx 为何中招
PHP2Shell 双 RCE 已遭在野利用:WordPress、Drupal 全在射程内,nginx 其实另有洞。拆成因与修复顺序
PHP2Shell 漏洞拆解:WordPress 与 nginx 为何中招
|
8天前
|
开发者 索引
DeepSeekHarness大肥鱼自带插件市场了?加个地址就能用
Open Plugin Market 是一个开放插件索引平台,收录800+优质DSH插件,支持分类浏览、智能推荐与随机发现。无需安装市场,粘贴索引地址即可一键接入,网页版直访 dshopen.org,助力小开发者被看见。(239字)
1746 1
DeepSeekHarness大肥鱼自带插件市场了?加个地址就能用
|
6天前
|
人工智能 Linux API
Magpie, 轻量本地AI网关!免费Token用不完!
Magpie 是开源AI编程模型调度网关,上线一月获1.8万Star。它通过本地高性能网关统一托管多平台API密钥、账号与免费额度,实现跨Agent的模型秒级切换、静默额度轮换与资源复用,显著降低碎片化管理成本。(239字)
Magpie, 轻量本地AI网关!免费Token用不完!
|
6天前
|
安全 程序员 应用服务中间件
PHP 被曝两大致命漏洞,请所有程序员抓紧做这件事!
PHP 官方发布了紧急安全更新,一口气修复了两个严重漏洞。如果网站和服务器用了 PHP 应该怎么处理?漏洞的原理是什么?本文给你讲清楚
704 0

热门文章

最新文章