从 GitLab 搬仓库到 AngusGit:公开项目直接导入,私有和内部项目推送 这篇讲内网 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 youexample.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-serviceplatform/order-serviceplatform/backend-order-serviceplatform/frontend/order-webplatform/order-webplatform/frontend-order-web方式一的地址短但不同子组下有同名项目时会撞名。方式二不会撞名地址稍长。拿不准就用方式二。还要检查项目名里有没有点号。AngusGit 的仓库名只能用中文、字母、数字、连字符和下划线点号会被去掉例如docs.site要提前改成docs-site。4. 私有和内部项目克隆后推送在 AngusGit 建团队和空仓库按第 3 节定好的规则先在 AngusGit 建好团队再在团队下建同名的空仓库。新建仓库时添加 README 文件、添加 .gitignore、选择许可证三项都不要勾选。任何一项勾上仓库就不再是空的推送时会被拒绝。从 GitLab 完整克隆用你自己的 GitLab 账号克隆。GitLab 开了双因素认证时HTTPS 的密码一栏要填 GitLab 的个人访问令牌权限勾选read_repository就够了。--bare会把 GitLab 上的所有分支和标签都拉下来不生成工作区。主分支叫 master 时先改名AngusGit 新建的空仓库默认分支是main。GitLab 项目的主分支叫master时先在本地改名已经是main就跳过。改名之后团队成员的本地习惯、GitLab CI 里写死的分支名都要跟着改成main。推送所有分支和标签第一行推所有分支第二行推所有标签。HTTPS 的用户名填 AngusGit 登录名密码填一把勾了git:write的访问令牌。用 SSH 地址也可以。对应的完整命令如下。gitlab.example.com和platform/backend-order-service都要换成你的地址并先建成空仓库。主分支已经叫main时跳过git branch -m。推送用的 HTTPS 地址换成你的空仓库私有仓库克隆时会要访问令牌按开头生成git:write令牌不要把令牌写进文章或截图。gitclone--barehttps://gitlab.example.com/platform/backend/order-service.gitcdorder-service.gitgitbranch-mmaster maingitpush https://git.anguskit.com/platform/backend-order-service.git--allgitpush 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然后执行whileread-rsrc dst;dogitclone--barehttps://gitlab.example.com/${src}.gittmp.git||continuegit-Ctmp.git branch-mmaster main2/dev/nullgit-Ctmp.git pushhttps://git.anguskit.com/${dst}.git--allgit-Ctmp.git pushhttps://git.anguskit.com/${dst}.git--tagsrm-rftmp.gitdonerepos.txt脚本逐行克隆、改名、推送然后删掉本地副本。运行之前先按开头手动搬一个仓库让系统的凭据管理器记住 GitLab 和 AngusGit 两边的令牌否则脚本每一行都会停下来问密码。AngusGit 的批量导入也能一次处理很多地址但它和单个导入一样只读公开项目、只带当前文件而且导入的仓库全部是公开的。内网 GitLab 的项目用上面的脚本更合适。6. 验收两边的分支和标签要一模一样每个仓库推完对比两边的分支和标签。下面的命令分别列出 GitLab 和 AngusGit 上所有分支、标签指向的提交再逐行比较diff\(gitls-remote--heads--tagshttps://gitlab.example.com/platform/backend/order-service.git|sort)\(gitls-remote--heads--tagshttps://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.yamlWebhook否在仓库设置 → Webhooks里重新添加8. 出错时你看到的原因怎么处理导入时提示源仓库URL「…」无效或无法正常访问项目是内部或私有的填的是 SSH 地址或者 AngusGit 服务器连不上 GitLab内部和私有项目按第 4 节推送。公开项目确认填的是 HTTPS 地址并在 AngusGit 服务器上执行git ls-remote 地址检查网络克隆 GitLab 时HTTP Basic: Access deniedGitLab 开了双因素认证或者密码不对密码一栏改填 GitLab 个人访问令牌推送时! [rejected] main - main (fetch first)AngusGit 上的仓库不是空的删掉重建一个三项都不勾的空仓库推送时repository … not foundAngusGit 上还没建这个仓库或者所有者、仓库名和第 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对比验收。参考文章AngusGit 手册仓库新建、导入、批量导入AngusGit 手册组织与权限团队、访问令牌导入 Git 仓库填一个源地址拿到默认分支的代码从 GitLab 迁到 AngusGit迁移清单、双跑和回滚HTTPS 克隆私有仓库密码填访问令牌