离开 GitHub 前必做:把仓库导出为 Markdown 完整指南

离开 GitHub 前必做:把仓库导出为 Markdown 完整指南

URL to Anyon 17 days ago

Forgejo 的「Leaving GitHub for Forgejo」帖子上个月在 Hacker News 拿了 521 个赞,紧接着「双胞胎兄弟抹掉 96 个政府数据库」又冲到 285 分。两则不相关的新闻,底下藏的是同一种担忧:如果托管平台明天没了,除了代码我还会丢什么?

git clone 能救回提交和分支,救不回 README、Wiki、十年的 issue 讨论、release notes、GitHub Pages 站点、Discussions。这些「非代码」内容才是团队的集体记忆,它们活在渲染后的 HTML 页面上,不在 .git 里。

这篇教程拆解 6 个步骤:在迁移到 Forgejo(或只是给 GitHub 留一份保险)之前,怎么把仓库 README、Wiki、Issues、Releases、Pages 全部导出为 Markdown、PDF、JSON。示例用 URL to Markdown 演示,工作流本身和你已经在用的任何 URL 转换工具或抓取脚本都通用。最近更新:2026-05-14。

Banner

目录

为什么离开 GitHub 前要先备份非代码内容?

要备份 GitHub 内容,是因为 git clone 只复制源代码本身,把 Wiki 页面、issue 讨论、release notes、Discussions、Pages 站点都留在了 GitHub 的服务器上 —— 账号被封、仓库被设私有、平台政策变更,这些内容就一夜消失。把这层渲染后的内容导出为 Markdown 这样的便携格式,是把团队记忆握回自己手里的唯一办法。

2025–2026 年发生的三件事把这件事从「最佳实践」变成「你早该做了」:

  • Forgejo 迁移潮。Hacker News 上「Leaving GitHub for Forgejo」帖 24 小时内冲破 500 赞,多个高 star 仓库的维护者同一周发布了迁移指南。
  • 数据消失的提醒。「双胞胎兄弟抹掉 96 个政府数据库」(HN 285 分) 讲的是政府工具,不是 Git 托管,但它和迁移潮同一周登上热榜,传达的信息一致:托管数据从来都不是你的。
  • 欧洲数据主权讨论。HN 877 分的「欧洲数字栈」帖把自托管 Git 拉进了和云厂商同一层的关键基础设施讨论。

Git 本身是便携的,github.com 在 Git 之外加上去的所有东西都不是。这篇就是补这部分。

准备工作

进入 Step 1 之前简单清单:

  • 一份要备份的仓库列表(一个一个来即可,批量脚本放在 Tips 里)。
  • 每个中等规模仓库(< 200 issues、< 10 Wiki 页、< 20 releases)大约 30–45 分钟,规模线性放大。
  • 一个 URL 转换工具。本文用 URL to Markdown 和它的同套工具(URL to JSON、URL to PDF、URL to HTML)演示截图;如果你习惯用 pandocmonolith 或自建 headless 脚本,步骤一一对应。
  • 一个目标文件夹,按日期命名:~/backups/github/2026-05-14/<owner>-<repo>/

本文绝大部分步骤不需要 GitHub API token —— 每个示例 URL 都是公开渲染页。如果是私有仓库,先在浏览器登录 GitHub,再用 raw.githubusercontent.com 路径,Step 1 里有细节。

Step 1:把 README、Wiki、Discussions 导出为 Markdown

把仓库 README 导出为 Markdown,最简单的办法是复制原始路径(https://raw.githubusercontent.com/<owner>/<repo>/main/README.md),粘贴进 URL-to-Markdown 转换器 —— 不到 5 秒就拿到一份保留标题、围栏代码块、链接的 .md 文件,直接提交到 Forgejo 或本地存档都可以。

三类目标,思路一致:

  • READMEhttps://github.com/<owner>/<repo>/blob/main/README.md
    • 经验:用 raw URL(raw.githubusercontent.com/...)拿到的输出更干净,没有 GitHub 页面元素。
  • Wiki 页https://github.com/<owner>/<repo>/wiki/<Page-Name>
    • GitHub Wiki 本身是个 Git 仓库,你也可以 git clone https://github.com/<owner>/<repo>.wiki.git。但用 URL 转换器拿到的渲染版本会自动把相对链接展开为绝对路径,并保留嵌入图片。
  • Discussionshttps://github.com/<owner>/<repo>/discussions/<number>
    • 一条 discussion 一个文件,保留回复顺序、代码块、反应数(以纯文本形式)。

URL to Markdown 的实操:

  1. 粘贴 GitHub URL。
  2. 点 Convert。典型 README 输出 2–4 秒。
  3. 在日期目录下另存为 README.mdwiki-<page>.mddiscussion-<number>.md

输出里你会看到:

# Awesome Project

> 一句话简介。

## Installation
```bash
pnpm install

License

MIT


代码围栏、引用块、相对链接绝对化都能存活。图片可能仍以 `![](relative-path)` 形式保留 —— 存档前用 `sed` 或脚本把相对路径前缀替换成绝对的 `https://raw.githubusercontent.com/<owner>/<repo>/main/<path>`。

## Step 2:Issues(含评论)导出为 Markdown + JSON

要把 GitHub issues 带评论一起存档,做两遍处理:每条 issue 单独 URL 走 URL to Markdown 拿到人可读副本,issue **列表页**走 URL to JSON 拿到结构化数据 —— 两者合起来覆盖「看」和「再导入」两种需求。

**A 遍 —— 单 issue Markdown(人读)**

URL 形式:`https://github.com/<owner>/<repo>/issues/<number>`

每条 issue 输出一份 `.md`,包含:

- 标题(H1)
- 作者与开关状态
- 原始正文
- 所有评论按时间顺序,附作者
- 关联 PR 与引用(纯文本形式)

这份是给以后搜索用的(「我们当时讨论过时区那个 bug 没?」),也是迁移时给人看的副本。Forgejo 和 Gitea 都能通过 API 重新导入 issue;Markdown 这份是给人,不是给机器。

**B 遍 —— issue 列表 JSON(结构化)**

URL 形式:`https://github.com/<owner>/<repo>/issues?state=all&page=<n>`

走 [URL to JSON](https://urltoany.com/url-to-json)。输出是结构化的逐条记录(title、number、state、labels、assignees、创建/关闭时间)。`page=N` 翻到没数据为止。

速率限制提醒:GitHub 公开页对登录与未登录用户的 HTML 几乎一样,所以大多数转换器能正常工作。issue 数量很大的仓库(数千条),把节奏控制在 1 issue / 2 秒,匿名浏览限速够用。

## Step 3:Releases 与发布说明导出为 PDF

把 GitHub release 存成 PDF,目标是**长期可信归档** —— 合规、法律、或者你只是想要一份单文件版本可以交给审计。URL 形式 `https://github.com/<owner>/<repo>/releases/tag/<tag>`,过 [URL to PDF](https://urltoany.com/url-to-pdf),拿到一份分页 PDF,包含 release 标题、发布日期、作者、完整 notes、附件二进制列表。

实战小技巧:在日期目录里把输出命名为 `releases/<tag>.pdf`(`releases/v1.4.2.pdf`)。PDF 哈希干净,你可以把 SHA-256 写进迁移日志 —— 哪天有人问「v1.4.2 当时到底发了什么」,你手里有一份哈希可验证的物证,不只是浏览器截图。

别忘了 CHANGELOG。仓库根目录有 `CHANGELOG.md` 的话 Step 1 已经覆盖;只在 Releases 页里的 changelog,Step 3 的 PDF 也包含。两份都留更稳。

## Step 4:整页快照 —— Image 与 HTML

要捕捉 GitHub 仓库页面的完整视觉布局(badge、社交预览图、代码高亮、嵌入图表),把 URL 转成 Image(PNG)拿到扁平快照,再转成 HTML 拿到离线可浏览版本。这两个格式补的是 Markdown 留下的缺口:页面**长什么样**。

适用场景:

- **带图表的 README**(Mermaid、Excalidraw、自己手画的 PNG)。
- **仓库首页**,README 加 badge、社交链接、侧栏元信息一起渲染。
- **PR 页面**,diff 本身就是信息。

两种格式分工:

- **URL to Image**(PNG/JPEG):扁平快照 —— 快、兼容性好、便于以后做视觉 diff。URL 任意子页面都可。
- **URL to HTML**:内联 CSS 的自包含 `.html` 文件,离线打开任何浏览器都能用,链接保留、排版保留。要**浏览**存档(不是看图)时用。

> **工具提示:** 想从一次 URL 粘贴里同时拿到 Markdown / JSON / PDF / Image / HTML 五种输出,[URL to Any](https://urltoany.com) 整套捆在一起,本文示例都在这里跑。如果你更习惯自己脚本拼接,整体工作流不变。

## Step 5:GitHub Pages 站点镜像为 Markdown

要把 GitHub Pages 站点镜像到本地,第一步拉它的 `sitemap.xml`(`https://<owner>.github.io/<repo>/sitemap.xml`),再把列出的每个页面 URL 过 URL-to-Markdown —— 你拿到的是站点全量 Markdown 副本,可以直接塞进 MkDocs、Docusaurus 或 Forgejo Pages 等价物。

按站点规模分两条路:

- **小站点(< 30 页)**:手动把每个 URL 粘进 URL to Markdown,5 分钟完事。
- **大站点**:拿 `sitemap.xml`,解析所有 `<loc>`,批量过转换器 API 或 headless 脚本。输出按原 URL 路径结构保存(`/getting-started/install/` → `getting-started/install.md`)。

这一步输出还有一个隐藏价值:等你拿到全站 Markdown 后,换 SSG(静态站点生成器)就变成搜索-替换工作,而不是重写。

## Step 6:用 AI Summarizer 生成迁移摘要

跑完 Step 1–5 后,每个仓库一个目录,可能加起来几十个。Step 6 是给这堆目录做索引:给每个仓库生成 150–300 字摘要,回答「这是什么、为什么存在、谁在用、停在了哪里」。把 README URL 丢进 [AI Summarizer](https://urltoany.com/ai-summarizer),让它出摘要,保存为各仓库备份目录顶部的 `_summary.md`。六个月后你回头看 `org-internal-experiment-2024-q3` 这种目录名,未来的自己会感谢你。

`_summary.md` 模板:

```markdown
# <repo-name>

**用途:** 一句话。
**迁移时状态:** archived / active / paused。
**主要维护者:** 姓名。
**关键依赖:** 内部/外部。
**本次备份包含:** README、Wiki(N 页)、Issues(N 条,N 个 open)、Releases(N 个)。
**迁移计划:** Forgejo / GitLab / 仅归档。

body_image_1

实战 Tips

跑过 40 多个仓库后总结的几条:

  • 每个目录加日期2026-05-14-backup/latest/ 强一百倍。你一定会再跑一次,那时候你会想 diff。
  • README 导出顶部钉一行 commit SHA。写明本次从哪个 commit 导出。迁移审计最爱这种细节。
  • 大改动后重导。把这步当成 release 产物,不是「一次性备份」。README 每月重写,导出也每月重做。
  • issue 列表显式分页。部分转换器会在 page 1 静默停下。手动 ?page=1?page=2 循环,直到返回空。
  • URL 导出 + git push --mirror 双管齐下。Markdown 和 PDF 覆盖外壳,git push --mirror <新远程> 覆盖代码、分支、tag、refs。两者加起来才是一份真正的备份。

body_image_2

Forgejo 迁移前 10 条 checklist

切 DNS、把仓库、把 CI 指向 Forgejo(或任何替代)之前,逐条确认:

  1. 代码已镜像 —— 每个分支和 tag 都跑过 git push --mirror <forgejo-remote>
  2. README + Wiki 已导出为 Markdown(Step 1)。在意 Wiki 编辑历史的话,额外 git clone .wiki.git
  3. Issues 已归档 —— 每条 Markdown + 列表 JSON(Step 2)。Forgejo importer 也能直接拉,但本地副本是兜底。
  4. Pull request 至少把已 merged 的存下来。PR 页和 issue 一样导出;patch(?diff=split)转 HTML 留作以后看。
  5. Releases 存 PDF + 二进制附件本地下载(Step 3)。Forgejo 不会自动回填二进制 release artifact。
  6. GitHub Pages 站点已镜像为 Markdown(Step 5),等 Forgejo Pages 上线后重指 DNS。
  7. Webhook URL 已记录 —— 写进私有笔记。不要把原始 secret 导出来;只记下指向哪、之后在 Forgejo 上重建。
  8. 分支保护规则截图或抄录。Forgejo 的等价命名不同,需要手动映射。
  9. CI workflow 已 review —— GitHub Actions YAML 在 Forgejo Actions 上多数小改即可跑,但 uses: actions/checkout@v4 这种 pinned action 需要换成 Forgejo 上的对应镜像。
  10. Fork、Star、Watcher 不会转过来。在 _summary.md(Step 6)里记下 fork 链;想感谢的核心贡献者直接私信。

这些是迁移一周后大家发现「我以为 import 都搞定了」时被反咬的地方。import 永远搞不定全部。

FAQ

Q:私有仓库的 README 也能导出为 Markdown 吗?

A:可以 —— 先在同一个浏览器登录 GitHub,再把 raw.githubusercontent.com/<owner>/<repo>/main/README.md 这种 raw URL 粘进客户端运行的 URL-to-Markdown 转换器。服务端转换器走 API:生成 contents:read 权限的细粒度 token,先用 API 拉 raw 文件,再转换。

Q:URL to Markdown 会保留图片和代码块吗?

A:代码块保留 —— 围栏代码块和缩进代码块都干净留存。图片保留为 Markdown 链接(![](url)),但相对路径只有部分转换器会改写成绝对 GitHub URL;如果你用的那个不改,就用一行 sed 把相对路径加前缀 https://raw.githubusercontent.com/<owner>/<repo>/<branch>/

Q:这一切跟 git clone 有什么区别?

A:git clone 拷的是 Git 仓库本身:commit、分支、tag、源文件。它拷 GitHub 渲染出来的那一层:Wiki 页(在另一个 .wiki.git 里)、issue 讨论、release notes、Discussions、GitHub Pages、各种 UI 元信息。把 GitHub repo 导出为 Markdown 就是补上这一层,正好是 git clone 漏掉的部分。

Q:整套流程要 GitHub API token 吗?

A:公开仓库不需要 —— 用到的每个 URL 都是公开渲染页。私有仓库需要:浏览器端登录,或者服务端用带 token 的 API。token 只要 contents:read(文件)和 issues:read(issue),不要给更多。

Q:50 个以上的仓库怎么最快备份?

A:两条管线并行。代码for repo in $(cat repos.txt) 循环里 git push --mirror 到新主机,每个仓库几分钟。非代码:脚本把每个仓库的 URL 列表(README、wiki 索引、issue 列表、releases)喂给转换器。普通笔记本 4 小时以内 50 个仓库跑完,绝大多数时间无人值守。

总结

代码本身是便携的,GitHub 上围绕代码的东西 —— Wiki、issues、releases、Pages、Discussions —— 都活在渲染后的 HTML 里,账号一没就全没。这 6 步把剩下的部分覆盖了:

  1. README、Wiki、Discussions → Markdown
  2. Issues → Markdown + JSON
  3. Releases → PDF
  4. 整页快照 → Image + HTML
  5. GitHub Pages → Markdown
  6. 每仓库一句话摘要 → AI Summarizer

跑一遍,输出按日期文件夹存好,迁移 Forgejo(或 GitLab、自托管 Gitea)就从「内容丢失灾难」降级成「代码导入工作」。下一次 Hacker News 又掀起一波迁移潮的时候,你已经先一步在岸上了。


在你自己的仓库上试一遍。 URL to Any 覆盖以上六种输出 —— Markdown、JSON、PDF、Image、HTML、AI 摘要 —— 一次粘贴 URL 全拿到。免费、不用注册、每次转换大约 2 秒。挑你 org 里最吵那个仓库,把 Step 1–6 跑一遍,看看有多少东西本来根本进不了 git