From GitHub to Codeberg/Forgejo

From GitHub to Codeberg/Forgejo

从 GitHub 迁移至 Codeberg/Forgejo

Respect your users and their confidence in you, “Microsoft” GitHub. After years of waffling around I finally bit the bullet and migrated away from GitHub onto Codeberg and a private Forgejo instance. If Codeberg is good enough for Gentoo then it’s good enough for me. 请尊重你的用户以及他们对你的信任,“微软” GitHub。在犹豫多年后,我终于下定决心,从 GitHub 迁移到了 Codeberg 和一个私有的 Forgejo 实例上。如果 Codeberg 对 Gentoo 来说足够好,那么它对我来说也足够了。

What’s the problem with GitHub? One part of my GitHub aversion is me being anti the big American tech corporations for ideological reasons. I’d like to reduce my usage and dependence of Google/Facebook/Apple/Microsoft/Amazon etc where I can and moving away from GitHub fits that goal nicely. GitHub 有什么问题?我厌恶 GitHub 的部分原因在于,出于意识形态的考量,我反对美国大型科技公司。我希望在力所能及的范围内减少对 Google、Facebook、Apple、Microsoft、Amazon 等公司的使用和依赖,而离开 GitHub 正好符合这一目标。

The other reason is GitHub’s enshittification. GitHub has been slow and slightly buggy for years and it’s not getting better. They push out badly planned features while shipping this kind of code in GitHub actions runner: #!/bin/bash SECONDS=0 while [[ $SECONDS != $1 ]]; do : done (This apparently broke Zig and caused them to leave for Codeberg.) You may not like it but this is what peak vibe coding looks like. I know it’s a snarky comment, but with a CEO that says “embrace AI or get out” then it’s hard to resist. 另一个原因是 GitHub 的“屎化”(enshittification)。多年来,GitHub 一直运行缓慢且小毛病不断,而且情况并没有好转。他们一边推出规划糟糕的功能,一边在 GitHub Actions runner 中发布这样的代码:#!/bin/bash SECONDS=0 while [[ $SECONDS != $1 ]]; do : done(这显然导致了 Zig 的构建中断,并促使他们转向了 Codeberg)。你可能不喜欢它,但这正是“氛围编程”(vibe coding)的巅峰之作。我知道这句评论很刻薄,但面对一位宣称“拥抱 AI,否则滚蛋”的 CEO,很难不让人反感。

There’s empirical data to back up GitHub’s unreliability; just check out these uptime logs (taken 2026-04-27 from third party sites since the official status page predictably lies): 有实证数据支持 GitHub 的不可靠性;看看这些正常运行时间日志就知道了(数据于 2026 年 4 月 27 日从第三方网站获取,因为官方状态页面不出所料地在撒谎):

They don’t call it “Microslop” for nothing. 人们叫它“Microslop”(微软烂摊子)不是没有原因的。

Self-hosted + managed

自托管 + 管理

Codeberg is based on Forgejo, which is great to self-host. I’ve had it running a few weeks when I’ve been playing with my homelab and it feels exceptionally fast. The web UI is super responsive and I frequently have to double-check that I pushed as it finished so quickly. Codeberg 基于 Forgejo,非常适合自托管。我在折腾家庭实验室(homelab)时已经运行了它几周,感觉异常快速。Web UI 的响应速度极快,以至于我经常需要反复确认是否已经推送成功,因为它完成得太快了。

I would love to have the speed and privacy for all my repositories but I’ve got some that I want to be public (the source for this site for example). I considered a few different setups: 我希望所有的仓库都能拥有这种速度和隐私性,但我有一些仓库需要公开(例如本站的源码)。我考虑了几种不同的方案:

  • Sync back changes to GitHub via Forgejo’s built-in GitHub sync? (Keeping GitHub active would defeat the point a little though.)
  • Sync changes from my Forgejo instance to Codeberg? (Maybe annoying to manage multiple repos?)
  • Only use Codeberg? (I’d lose speed and privacy for my private repos.)
  • Expose my Forgejo instance running in my homelab? (The internet is a scary place.)
  • Setup a public Forgejo on my Hetzner VPS? (I’d still have to protect it and manage traffic.)
  • 通过 Forgejo 内置的 GitHub 同步功能将更改同步回 GitHub?(但保持 GitHub 活跃有点违背初衷。)
  • 将更改从我的 Forgejo 实例同步到 Codeberg?(管理多个仓库可能会很麻烦?)
  • 只使用 Codeberg?(我会失去私有仓库的速度和隐私。)
  • 将运行在家庭实验室的 Forgejo 实例暴露在公网?(互联网是个可怕的地方。)
  • 在我的 Hetzner VPS 上搭建一个公开的 Forgejo?(我仍然需要保护它并管理流量。)

In the end I decided to use Codeberg as for my public-facing repositories and Forgejo as my main interface (for both public and private repos). Some of my public repos are close to read-only (this site’s source for instance) so I’ve setup a mirror where Forgejo will push changes to Codeberg automatically. However, it’s weird to also pull changes from Codeberg to Forgejo. I guess I could setup a script to do it, but pull requests from others are rare enough that I can do it manually. Other repos (such as tree-sitter-djot) are left alone as they’re more collaborative in nature and I can’t be bothered to keep two sources in sync. 最终,我决定将 Codeberg 用于面向公众的仓库,并将 Forgejo 作为我的主要界面(同时管理公开和私有仓库)。我的一些公开仓库几乎是只读的(例如本站源码),所以我设置了一个镜像,让 Forgejo 自动将更改推送到 Codeberg。不过,从 Codeberg 拉取更改到 Forgejo 会比较奇怪。我想我可以写个脚本来处理,但来自他人的合并请求(Pull Request)很少,我可以手动完成。其他仓库(如 tree-sitter-djot)则保持原样,因为它们更具协作性,我不想费心去同步两个来源。

Is it good? Yes, both Codeberg and Forgejo are very good. They are snappy and speedy and there are no features I miss from either GitHub or GitLab (and plenty I’m glad to avoid—getting AI shoved into every crevice for instance). (Yes, I used an em-dash on purpose.) At the moment Codeberg is admittedly having periods with pretty bad performance issues. This is because they’ve been under a DDOS attack for quite some time, which has been frustrating. 它好用吗?是的,Codeberg 和 Forgejo 都非常棒。它们响应迅速、速度极快,我并没有怀念 GitHub 或 GitLab 的任何功能(反而很高兴能避开很多东西——比如 AI 被强行塞进每一个角落)。(是的,我特意用了破折号。)目前,Codeberg 确实在某些时段存在严重的性能问题。这是因为他们长期遭受 DDOS 攻击,这确实令人沮丧。

The migration

迁移过程

The migration wasn’t difficult, just a bit repetitive. For private repositories I just deleted them from GitHub and pushed them to Forgejo. Public repositories had a few more steps: 迁移并不困难,只是有点重复。对于私有仓库,我直接从 GitHub 删除并推送到 Forgejo。公开仓库则多了几个步骤:

  1. Push them to Forgejo
  2. Push them to Codeberg
  3. Add a header redirecting to Codeberg similar to this:
  4. Archive them on GitHub
  5. 推送到 Forgejo
  6. 推送到 Codeberg
  7. 添加一个重定向到 Codeberg 的头部信息,类似于这样:
  8. 在 GitHub 上归档它们

Published: April 28, 2026 in 969b804 发布于:2026 年 4 月 28 日,版本号 969b804