Gogs迁移至Gitea(win环境)

近来因为需要基于gogs建立轻量级的代码审查制,然而却发现gogs的合并分支部分存在问题。gogs只支持简单的合并分支,并没有推送白名单和审批功能,所以又看向了gitea,两者一脉同源,且也支持如上功能,并且支持从gogs迁移至gitea。

参考资料

思路

基础思路

文档提到只能使用 Gitea 1.0.x 的版本去做一开始的迁移,其他版本都不行

Download the file matching the destination platform from the downloads page. It should be 1.0.x version. Migrating from gogs to any other version is impossible.

然后接下来是用每个小版本里最后一个版本去做数据库迁移(issue里有部分人一次性1.0.2迁移到1.4.2的情况,概率会有一些问题,我采用了一个版本一个版本迁移的笨办法)

Launch every major version of the binary ( 1.1.4 → 1.2.3 → 1.3.4 → 1.4.2 → etc ) to migrate database.

下面是他们的版本(win x64 exe文件):

数据库部分

部分主要是源码的 /models/migrations/migrations.go 里的 Migration数组里绑定的方法,运行gitea就会执行这部分的代码去迁移数据库。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// This is a sequence of migrations. Add new migrations to the bottom of the list.
// If you want to "retire" a migration, remove it from the top of the list and
// update minDBVersion accordingly
var migrations = []Migration{
	// v0 -> v4: before 0.6.0 -> 0.7.33
	NewMigration("fix locale file load panic", fixLocaleFileLoadPanic),                           // V4 -> V5:v0.6.0
	NewMigration("trim action compare URL prefix", trimCommitActionAppURLPrefix),                 // V5 -> V6:v0.6.3
	NewMigration("generate issue-label from issue", issueToIssueLabel),                           // V6 -> V7:v0.6.4
	NewMigration("refactor attachment table", attachmentRefactor),                                // V7 -> V8:v0.6.4
	NewMigration("rename pull request fields", renamePullRequestFields),                          // V8 -> V9:v0.6.16
	NewMigration("clean up migrate repo info", cleanUpMigrateRepoInfo),                           // V9 -> V10:v0.6.20
	NewMigration("generate rands and salt for organizations", generateOrgRandsAndSalt),           // V10 -> V11:v0.8.5
	NewMigration("convert date to unix timestamp", convertDateToUnix),                            // V11 -> V12:v0.9.2
	NewMigration("convert LDAP UseSSL option to SecurityProtocol", ldapUseSSLToSecurityProtocol), // V12 -> V13:v0.9.37 
  ...
  ...
  // v102 -> v103
	NewMigration("update migration repositories' service type", dropColumnHeadUserNameOnPullRequest),
}

数据部分

根据文档的说明:

Copy gogs/data/ to gitea/data/. It contains issue attachments and avatars.

把Gogs安装目录下的data复制到Gitea安装下目录的data即可

页面模板

根据文档说明:

Copy custom templates, public from gogs/custom/ to gitea/custom/

上面说把Gogs安装目录下custom的templates和public复制到Gitea安装下目录的custom即可,但其实只是在v1.0可用,其余版本需要下载对应版本源码,把源码里的public和templates文件夹复制进去即可(取决于你运行的版本)。

下面是他们的历史版本(go 源码):

注意事项

  • 目前Gogs版本:v0.11.91
  • 想要升级到GItea版本:v1.10.2
  • 请务必一开始用 v1.0.2 操作

升级过程

  1. 新建目录gitea,把gogs安装目录下的custom(包括app.ini配置文件,配置文件的内容需要成修改gitea的绝对路径)和data目录置入其中,并放入 v1.0.2 的 gitea.exe文件。
  2. 在目录下运行 gitea web cmd命令进行迁移。
  3. 迁移完成使用下一个版本的 gitea.exe 重复一下动作(1.0.2 → 1.1.4 → 1.2.3 → 1.3.4 → 1.4.2 → … → 1.10.2)
  4. 出现闪退情况请在log目录下查看gitea.log文件查找具体错误。
  5. 最终完成完成后在管理面板重置秘钥文件和钩子

遇到的问题

  1. 索引仅支持767byte

具体错误:

[…itea/routers/init.go:60 GlobalInit()] [E] Failed to initialize ORM engine: migrate: do migrate: Sync2: Error 1709: Index column size too large. The maximum column size is 767 bytes.

解决方法:

  1. 在mysql配置项下[mysqld]添加如下配置并重启
1
2
3
4
5
...

innodb_file_format = barracuda

innodb_file_per_table = true

innodb_large_prefix = true

innodb_default_row_format = dynamic //PS: mysql5.7以上才支持该属性
  1. 修改表类型为动态表
 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
ALTER TABLE access ROW_FORMAT=DYNAMIC;
ALTER TABLE access_token ROW_FORMAT=DYNAMIC;
ALTER TABLE action ROW_FORMAT=DYNAMIC;
ALTER TABLE attachment ROW_FORMAT=DYNAMIC;
ALTER TABLE collaboration ROW_FORMAT=DYNAMIC;
ALTER TABLE comment ROW_FORMAT=DYNAMIC;
ALTER TABLE commit_status ROW_FORMAT=DYNAMIC;
ALTER TABLE deleted_branch ROW_FORMAT=DYNAMIC;
ALTER TABLE deploy_key ROW_FORMAT=DYNAMIC;
ALTER TABLE email_address ROW_FORMAT=DYNAMIC;
ALTER TABLE external_login_user ROW_FORMAT=DYNAMIC;
ALTER TABLE follow ROW_FORMAT=DYNAMIC;
ALTER TABLE gpg_key ROW_FORMAT=DYNAMIC;
ALTER TABLE hook_task ROW_FORMAT=DYNAMIC;
ALTER TABLE issue ROW_FORMAT=DYNAMIC;
ALTER TABLE issue_assignees ROW_FORMAT=DYNAMIC;
ALTER TABLE issue_label ROW_FORMAT=DYNAMIC;
ALTER TABLE issue_user ROW_FORMAT=DYNAMIC;
ALTER TABLE issue_watch ROW_FORMAT=DYNAMIC;
ALTER TABLE label ROW_FORMAT=DYNAMIC;
ALTER TABLE lfs_lock ROW_FORMAT=DYNAMIC;
ALTER TABLE lfs_meta_object ROW_FORMAT=DYNAMIC;
ALTER TABLE login_source ROW_FORMAT=DYNAMIC;
ALTER TABLE milestone ROW_FORMAT=DYNAMIC;
ALTER TABLE mirror ROW_FORMAT=DYNAMIC;
ALTER TABLE notice ROW_FORMAT=DYNAMIC;
ALTER TABLE notification ROW_FORMAT=DYNAMIC;
ALTER TABLE org_user ROW_FORMAT=DYNAMIC;
ALTER TABLE protected_branch ROW_FORMAT=DYNAMIC;
ALTER TABLE public_key ROW_FORMAT=DYNAMIC;
ALTER TABLE pull_request ROW_FORMAT=DYNAMIC;
ALTER TABLE reaction ROW_FORMAT=DYNAMIC;
ALTER TABLE `release` ROW_FORMAT=DYNAMIC;
ALTER TABLE repo_indexer_status ROW_FORMAT=DYNAMIC;
ALTER TABLE repo_redirect ROW_FORMAT=DYNAMIC;
ALTER TABLE repo_unit ROW_FORMAT=DYNAMIC;
ALTER TABLE repository ROW_FORMAT=DYNAMIC;
ALTER TABLE star ROW_FORMAT=DYNAMIC;
ALTER TABLE stopwatch ROW_FORMAT=DYNAMIC;
ALTER TABLE team ROW_FORMAT=DYNAMIC;
ALTER TABLE team_repo ROW_FORMAT=DYNAMIC;
ALTER TABLE team_user ROW_FORMAT=DYNAMIC;
ALTER TABLE topic ROW_FORMAT=DYNAMIC;
ALTER TABLE tracked_time ROW_FORMAT=DYNAMIC;
ALTER TABLE two_factor ROW_FORMAT=DYNAMIC;
ALTER TABLE u2_f_registration ROW_FORMAT=DYNAMIC;
ALTER TABLE upload ROW_FORMAT=DYNAMIC;
ALTER TABLE user ROW_FORMAT=DYNAMIC;
ALTER TABLE user_open_id ROW_FORMAT=DYNAMIC;
ALTER TABLE version ROW_FORMAT=DYNAMIC;
ALTER TABLE watch ROW_FORMAT=DYNAMIC;
ALTER TABLE webhook ROW_FORMAT=DYNAMIC;
  1. index列不存在

具体错误:

[…itea/routers/init.go:60 GlobalInit()] [E] Failed to initialize ORM engine: migrate: do migrate: Error 1054: Unknown column ‘index’ in ‘field list’

解决方法:

源码搜索得知 repo_unit 表缺少类型为 int 的 index 列,加上即可。

1
ALTER TABLE `repo_unit` ADD COLUMN `index` int(11) NULL DEFAULT NULL AFTER `type`;
  1. 表 external_login_user 不存在

具体错误:

[…itea/routers/init.go:60 GlobalInit()] [E] Failed to initialize ORM engine: migrate: do migrate: Find: Error 1146: Table ‘external_login_user’ doesn’t exist

解决方法:

创建表即可

 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
CREATE TABLE `external_login_user` (
`external_id`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`user_id`  bigint(20) NOT NULL ,
`login_source_id`  bigint(20) NOT NULL ,
`raw_data`  text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`provider`  varchar(25) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`email`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`name`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`first_name`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`last_name`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`nick_name`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`description`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`avatar_url`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`location`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`access_token`  text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`access_token_secret`  text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`refresh_token`  text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`expires_at`  datetime NULL DEFAULT NULL ,
PRIMARY KEY (`external_id`, `login_source_id`),
INDEX `IDX_external_login_user_user_id` (`user_id`) USING BTREE ,
INDEX `IDX_external_login_user_provider` (`provider`) USING BTREE 
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
ROW_FORMAT=DYNAMIC;

最终结果

正在加载 Disqus 评论,你可能需要科学上网才能正常加载Disqus.
lamu
隐藏