批量迁移 GitLab 仓库到 Forgejo

前言

在上一篇中,我们讲了从 GitLab 迁移至 Forgejo 的相关内容。尽管在安装完 Forgejo 之后,其各方面资源使用率有了大幅度的下降,但 GitLab 上所积累的项目还没有迁移。毕竟,GitLab 已被使用了三年多了,期间创建了数十个项目。如果通过页面挨个填写参数来进行迁移,无疑会耗费大量的时间与精力,操作过程也极为繁琐。因此,在本文中,我们将直接借助接口来实现仓库的批量迁移,以提升迁移效率,简化操作流程。

批量迁移实现

通过利用 Forgejo 自身所提供的迁移 API,我们能够直接从 GitLab 迁移仓库。这种迁移方式不仅简单便捷,而且效率颇高。由于在本次迁移过程中,我们并没有编写可复用脚本的必要,所以可以直接在浏览器的 console 中执行代码,这样一来,获取 Forgejo Token 以及通过 Node 执行等步骤都能够省略,进一步简化了操作流程。

GitLab 获取令牌

在调用接口之前,首要任务是获取 GitLab 的个人访问令牌。具体操作如下:首先打开 GitLab 用户设置界面,接着点击访问令牌菜单,然后点击添加新令牌选项。

此时,会弹出相应的页面,我们需要在其中输入令牌名字,并勾选 api 以及 read_respoitory 这两个选项,最后点击创建个人访问令牌按钮。

创建完成后,务必复制个人访问令牌并妥善保存,因为在后续的迁移操作中将会用到该令牌。

获取迁移接口

由于我们此次没有编写复用脚本的需求,并且迁移功能相对较为简单,所以我们可以直接在浏览器中创建一个迁移请求,并将其复制下来以便复用。

首先,打开 Forgejo 页面,随后点击添加 -> 开始迁移选项,接着在弹出的页面中选择 GitLab。

在该页面中,我们需要输入仓库 URL 以及刚才所复制的 GitLab 个人访问令牌,而下方的其他配置则可根据实际需求进行选择。

在此过程中,需要提前打开浏览器控制台,并在 console 页面勾选 preserve log 选项。这是因为迁移接口在执行之后,页面会发生跳转,从而导致控制台被清空。而勾选 保存日志 选项,则能够确保我们在迁移过程中所产生的日志信息得以完整保存,方便后续查看和复制。

完成上述操作后,我们在控制台的日志信息中找到 migrate 这个请求日志,然后右键点击 copy -> Copy as fetch,将这个请求复制下来。此时,我们便获取到了完整的请求方法,后续只需要对 URL、描述等信息进行相应的修改,即可迁移其他仓库。

将请求粘贴到控制台中后,我们可以发现,实际上只需要 clone_addrrepo_namedescription 这三个参数即可完成迁移操作。如果想要测试该请求是否可用,只需将 repo_name 修改为其他名字,然后执行请求即可进行测试。

GitLab 获取所有仓库

为了能够更加高效地迁移仓库,我们需要通过 GitLab API 直接读取当前用户下所有可访问的项目。这样一来,我们便能够直接获取项目的 url、描述、名称等信息,无需手动整理组装列表,从而进一步提高迁移效率。

以下是通过 JavaScript 代码实现获取 GitLab 所有仓库信息的示例:

1
2
3
4
fetch('https://jihulab.com/api/v4/projects')
.then(res => res.json())
.then(console.log)
.catch(console.error)

需要注意的是,GitLab Api 所有列表接口都存在分页机制,默认情况下只能查询 20 条数据。若要查询更多数据,则需要添加分页参数。

GitLab API 分页

在接口中添加 page(页码)以及 per_page(分页数量)参数,即可实现数据的分页查询。

在接口的 Response Header 中,我们可以获取到分页信息,例如当前页码、总页数、项目总数等。

具体信息如下表所示:

Header Description
x-next-page 下一页的索引。
x-page 当前页面的索引(从 1 开始)。
x-per-page 每页的项目数。
x-prev-page 上一页的索引。
x-total 项目总数。
x-total-pages 总页数。

通过这些分页信息,我们可以更加灵活地控制数据的查询与获取,确保能够完整地获取到所有需要迁移的仓库信息。

完整代码

以下是实现 GitLab 仓库迁移至 Forgejo 的完整 JavaScript 代码示例。在使用该代码时,需要将 GitLabToken 替换为自己在 GitLab 中获取的个人访问令牌,另外,还需要根据实际需求对 migrateRepo 函数中的请求参数进行相应的修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
* @Author: zi.yang
* @Date: 2024-11-18 23:48:29
* @LastEditors: zi.yang
* @LastEditTime: 2024-11-22 19:45:32
* @Description: GitLab 仓库迁移至 Forgejo
* @FilePath: /gitee-to-forgejo/src/migrate.js
*/

// GitLab Token
const GitLabToken = "your_gitlab_token"

/**
* Forgejo 迁移仓库 API
* @param {*} url
* @param {*} repoName
* @param {*} description
* @returns
*/
function migrateRepo(url, repoName, description) {
return fetch("http://127.0.0.1:3000/repo/migrate", {
"headers": {
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-language": "zh-CN,zh;q=0.9",
"cache-control": "max-age=0",
"content-type": "application/x-www-form-urlencoded",
"sec-ch-ua": "\"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"macOS\"",
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "same-origin",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1"
},
"referrerPolicy": "no-referrer",
"body": `_csrf=&service=4&clone_addr=${encodeURI(url)}&auth_token=${GitLabToken}&mirror=on&lfs_endpoint=&uid=1&repo_name=${repoName}&private=on&description=${description}`,
"method": "POST",
"mode": "cors",
"credentials": "include"
}).then(res => res.text())
}

/**
* GitLab 仓库列表
*/
fetch('https://gitlab.com/api/v4/projects?simple=true&per_page=100', {
headers: { "PRIVATE-TOKEN": GitLabToken }
}).then(res => res.json()).then(async (repoList) => {
/**
* 循环迁移仓库
*/
for (const repo of repoList) {
await migrateRepo(repo.web_url, repo.name, repo.description).then(() => {
console.log(`${repo.name} 已迁移`)
}).catch(err => {
console.error(`${repo.name} 迁移失败`, err)
})
}
}).catch(console.error)

迁移报错

在迁移过程中,可能会遇到:您不能从不允许的主机导入 这样的报错信息。若出现此类报错,需要对 Forgejo 的 app.ini 配置文件进行修改。

app.ini 文件尾追加下面两行配置,这样就可以访问所有目标主机。若只想限制只访问某些特定的主机地址,则可以指定相应的 IP 地址和域名,例如 *.github.com, github.com

1
2
[migrations]
ALLOWED_DOMAINS = *.*.*

修改完成后,保存 app.ini 文件并重启 forgejo 服务,然后重新尝试迁移操作,此时应该能够顺利进行迁移。

结语

至此,我们已经完成了 GitLab 仓库的批量迁移工作。实际上,整个迁移过程主要是借助了 Forgejo API 与 GitLab API 来实现的,并没有涉及过于复杂的技术或操作。不过需要注意的是,在执行完 migrate api 后,并不意味着迁移已经完全结束。此时,只是在 Forgejo 平台上创建了相应的仓库,实际的迁移任务会在后台继续执行。因此,我们需要耐心等待所有任务迁移完成。

相关链接


批量迁移 GitLab 仓库到 Forgejo
https://blog.pangcy.cn/2024/11/22/服务器运维/Git/批量迁移 GitLab 仓库到 Forgejo/
作者
子洋
发布于
2024年11月22日
许可协议