## 🪜 Learning Ladder: Git 管理项目与 GitHub 自动化

*这条 5 级路径会带你从“会保存代码”走到“能用 Git 管理真实项目，并用 GitHub Actions 自动检查、测试、发布”。这是一个偏技术实践的主题：核心不是背命令，而是建立可追踪、可协作、可自动化交付的工作流。别跳级——Git 的基础概念越稳，后面的协作和自动化越轻松。*

| Level | Name | What You'll Be Able To Do |
|---|---|---|
| 1 | 本地版本管理 | 用 Git 在本地记录项目变化，能安全提交、查看历史、撤销小错误 |
| 2 | GitHub 远程协作 | 把项目托管到 GitHub，理解远程仓库、Pull Request 和基本协作流程 |
| 3 | 分支工作流 | 用分支开发功能、修复冲突、保持主分支稳定 |
| 4 | GitHub 自动化 | 用 GitHub Actions 自动运行检查、测试和构建 |
| 5 | 可维护交付流程 | 设计稳定的项目管理与自动化流程，能排查 CI 问题并指导团队使用 |

### Level 1: 本地版本管理

**1. 这个阶段要理解什么**
你先要把 Git 理解成“项目时间机器”，而不是一个神秘命令行工具。这个阶段的目标是：你能在本地项目里记录清晰的修改历史，并在犯错时知道如何回到安全状态。先不要急着学团队协作，单人项目的基本操作才是后面所有流程的地基。

**2. 掌握标准**
- 你可以从零初始化一个 Git 仓库，并完成多次有意义的提交。
- 你可以用 `git status`、`git diff`、`git log` 解释当前项目发生了什么。
- 你可以撤销工作区里的错误修改，或恢复某个文件到上一次提交的状态。
- 你可以写出清楚的提交信息，让别人看历史时知道“为什么改”。

**3. 核心概念与技能**
- **工作区 / 暂存区 / 仓库**：工作区是你正在改的文件，暂存区是准备提交的修改，仓库是已经保存下来的历史。
- **提交 commit**：一次提交应该是一组相关修改，不是“今天所有乱七八糟的改动”。
- **查看变化**：`git status` 看状态，`git diff` 看具体改动，`git log` 看历史。
- **安全撤销**：先学 `git restore` 和 `git restore --staged`，不要一上来乱用 `reset --hard`。
- **忽略文件**：用 `.gitignore` 排除依赖目录、缓存、密钥、构建产物等不该进仓库的文件。

**4. 里程碑：证明你准备好了**
创建一个小项目仓库，至少包含 8 次提交；每次提交只做一类事情，比如“初始化项目结构”“添加 README”“实现配置示例”“修复拼写错误”。最后用 `git log --oneline` 截图或复制输出，能看出清晰的演进历史。

**5. 动手练习 / 小项目**
做一个“项目日志仓库”，耗时约 2-3 小时。创建一个包含 `README.md`、`notes/`、`.gitignore` 的仓库，分 8-10 次提交逐步添加内容：项目说明、使用方式、待办列表、配置示例、一次错误修改和一次撤销。完成后，你应该能打开历史记录，清楚说出每次提交改了什么、为什么改。

**6. 这个阶段最常犯的错误**
- **把 Git 当成保存按钮**：很多新手每次提交都写 `update` 或 `fix`，因为只想“保存一下”。修正方法：提交前问自己“这次改动解决了哪一个具体问题？”然后把答案写进提交信息。
- **一次提交塞太多东西**：比如同时改 README、重构代码、修 bug。这样以后回滚或审查都困难。修正方法：用 `git diff` 检查改动，把不相关的修改拆成多次提交。
- **提交不该提交的文件**：例如 `node_modules/`、`.env`、日志文件。原因是没理解仓库应该保存源文件，不是保存所有本地文件。修正方法：项目开始就写 `.gitignore`，提交前总看 `git status`。
- **害怕撤销命令**：新手怕丢代码，所以错了也不敢改历史。修正方法：先只练习低风险命令：`git restore <file>`、`git restore --staged <file>`，理解后再学更强的命令。

**7. 进入下一阶段前的自测问题**
如果你改坏了一个文件但还没有提交，你能不能不用搜索，自己把它恢复到上一次提交的状态，并解释这个操作影响的是工作区还是仓库？

**8. 下一步**
当你能在本地稳定记录和解释项目历史后，就可以把仓库推到 GitHub，开始学习远程托管和协作流程。

### Level 2: GitHub 远程协作

**1. 这个阶段要理解什么**
GitHub 不是 Git 本身，而是托管 Git 仓库、讨论修改、追踪问题的平台。这个阶段你要把“我本地的项目”变成“别人也能看到、复制、审查、贡献的项目”。重点是理解本地仓库和远程仓库之间的同步关系。

**2. 掌握标准**
- 你可以创建 GitHub 仓库，并把本地项目推送到远程。
- 你可以克隆一个仓库，修改后通过分支和 Pull Request 提交变更。
- 你可以用 Issues 记录任务、bug 和改进建议。
- 你可以阅读 Pull Request 的文件改动，并留下具体评论。

**3. 核心概念与技能**
- **remote 远程仓库**：本地仓库可以连接 GitHub 上的远程地址，常见名字是 `origin`。
- **push / pull / fetch**：`push` 上传本地提交，`pull` 拉取并合并远程变化，`fetch` 只获取远程信息但不自动合并。
- **Pull Request**：PR 是“请求把某个分支的修改合进另一个分支”，也是代码审查和讨论的入口。
- **Issues**：Issue 用来记录任务和讨论，不应该只当 bug 列表。
- **README**：README 是项目门面，要说明项目是什么、怎么运行、怎么贡献。

**4. 里程碑：证明你准备好了**
把 Level 1 的项目发布到 GitHub；创建 3 个 Issues；为其中 1 个 Issue 新建分支、完成修改、发起 Pull Request，并在合并前写一段说明：这个 PR 解决了什么、怎么验证。

**5. 动手练习 / 小项目**
做一个“GitHub 协作模拟”，耗时约 3-5 小时。你可以自己扮演维护者和贡献者：先创建 Issue，再创建分支修改 README 或添加一个简单脚本，然后开 PR，检查 diff，写 review 评论，最后合并。完成结果应该包括：一个公开或私有 GitHub 仓库、至少 3 个 Issues、至少 1 个已合并 PR。

**6. 这个阶段最常犯的错误**
- **直接在主分支上改所有东西**：原因是觉得分支麻烦。问题是主分支会变得不稳定，也没法审查。修正方法：每个 Issue 都建一个短命名分支，例如 `docs/update-readme`。
- **不知道本地和远程谁更新**：常见表现是 push 被拒绝，提示远程有新提交。修正方法：先 `git fetch` 看远程情况，再决定 merge 或 rebase，不要盲目强推。
- **PR 描述太空**：只写“done”会让审查者不知道看什么。修正方法：PR 模板里固定写三件事：改了什么、为什么改、怎么测试。
- **Issue 写成一句情绪**：比如“登录坏了”。原因是没把问题变成可执行任务。修正方法：Issue 至少包含现象、复现步骤、期望结果、实际结果。

**7. 进入下一阶段前的自测问题**
你能不能画出或口头说明：本地分支、远程分支、Pull Request、主分支之间是什么关系？

**8. 下一步**
当你能用 GitHub 完成一次完整的“任务 → 分支 → PR → 合并”流程后，就该学习更真实的分支管理和冲突处理。

### Level 3: 分支工作流

**1. 这个阶段要理解什么**
真实项目不会只有一个人、一个改动、一个提交。你需要学会在不破坏主分支的前提下开发功能、修复 bug、同步别人改动，并处理冲突。这个阶段的关键心智是：分支不是备份文件夹，而是并行工作线。

**2. 掌握标准**
- 你可以为不同任务创建命名清晰的分支，并在完成后合并回主分支。
- 你可以解决简单和中等复杂度的 merge conflict，并验证结果正确。
- 你可以用 `git rebase` 或 `git merge` 同步主分支变化，并知道何时使用哪一个。
- 你可以把混乱的本地改动整理成可审查的提交和 PR。

**3. 核心概念与技能**
- **分支命名规则**：如 `feature/add-login`、`fix/readme-typo`、`chore/update-deps`，让人一眼看出目的。
- **merge vs rebase**：merge 保留合并节点，rebase 让提交历史更线性；个人功能分支常可 rebase，共享分支要谨慎。
- **冲突解决**：冲突不是 Git 出错，而是同一位置有不同修改，需要人判断保留哪部分。
- **小步提交**：小提交让冲突更容易定位，也让 PR 更容易审查。
- **stash 临时保存**：`git stash` 适合临时切换任务，但不能长期当仓库用。

**4. 里程碑：证明你准备好了**
在同一个仓库中创建两个分支，故意修改同一段 README 或同一个配置文件，制造一次合并冲突。手动解决冲突后合并，并在 PR 或提交说明里解释：冲突发生在哪里、你保留了哪些内容、为什么这样处理。

**5. 动手练习 / 小项目**
做一个“分支冲突训练场”，耗时约 4-6 小时。准备一个简单项目，创建 `feature/add-usage-section` 和 `feature/rewrite-intro` 两个分支，在同一文件相近位置做不同修改。先合并一个，再合并另一个，解决冲突，运行或检查项目，最后整理提交历史。完成结果应该是：主分支包含两个功能的最终内容，历史记录能看出分支合并过程。

**6. 这个阶段最常犯的错误**
- **冲突时随便删标记**：看到 `<<<<<<<`、`=======`、`>>>>>>>` 就慌，随便删到能提交为止。修正方法：先读懂三块内容分别来自哪里，再手动整理成最终正确版本。
- **在共享分支上乱 rebase 或 force push**：原因是想让历史好看，但可能改写别人依赖的历史。修正方法：只在自己的功能分支上 rebase；对团队共享分支先沟通。
- **分支长期不合主分支更新**：拖太久会导致冲突巨大。修正方法：功能分支工作超过 1-2 天时，定期同步 `main`。
- **PR 太大**：一次 PR 改几十个文件，审查者无法判断风险。修正方法：把任务拆小；一个 PR 最好只解决一个 Issue 或一个明确目标。

**7. 进入下一阶段前的自测问题**
如果两个分支改了同一段代码，你能不能解释 Git 为什么无法自动决定，并能手动合并出一个业务上正确的版本？

**8. 下一步**
当你能稳定管理分支和冲突后，就可以让 GitHub 在每次 PR 时自动帮你检查代码、运行测试和构建项目。

### Level 4: GitHub 自动化

**1. 这个阶段要理解什么**
GitHub Actions 的核心价值是：把“每次都要手动做的检查”变成“每次 push 或 PR 自动执行”。这个阶段你要从“人肉检查项目是否能跑”升级到“CI 自动检查项目是否健康”。先从简单的 lint、test、build 开始，不要一上来追求复杂发布流水线。

**2. 掌握标准**
- 你可以创建 `.github/workflows/*.yml` 工作流文件。
- 你可以在 push 或 pull request 时自动运行检查命令。
- 你可以阅读 Actions 失败日志，定位是哪一步失败。
- 你可以用状态检查保护主分支，阻止未通过检查的 PR 合并。

**3. 核心概念与技能**
- **workflow / job / step**：workflow 是一次自动化流程，job 是其中一组任务，step 是具体命令或 action。
- **触发器 on**：常见触发器是 `push`、`pull_request`、`workflow_dispatch`（手动触发）。
- **runner**：GitHub 提供的执行环境，比如 `ubuntu-latest`，你的命令会在这里运行。
- **actions/checkout**：常用 action，用来把仓库代码拉到 runner 上。
- **Secrets**：敏感信息要放在 GitHub Secrets，不能写进仓库文件。

**4. 里程碑：证明你准备好了**
为你的 GitHub 仓库添加一个 CI workflow：每次 PR 都自动执行至少两个检查，例如安装依赖和运行测试，或检查 Markdown 链接。故意制造一次失败，再修复它；保留 Actions 页面里一次失败和一次成功的运行记录。

**5. 动手练习 / 小项目**
做一个“最小 CI 流水线”，耗时约 4-8 小时。选择你的项目类型：如果是 Node.js 项目，就运行 `npm ci` 和 `npm test`；如果是文档项目，就运行 Markdown lint 或链接检查。创建 `.github/workflows/ci.yml`，打开 PR 触发检查，读日志，修复失败。完成结果应该是：PR 页面显示绿色通过状态，主分支合并前能看到自动检查结果。

**6. 这个阶段最常犯的错误**
- **YAML 缩进写错**：GitHub Actions 对缩进敏感，新手常因为少两个空格导致 workflow 不运行。修正方法：从最小可用模板开始，每加一段就提交测试。
- **本地能跑，CI 不能跑**：原因可能是依赖没锁定、环境变量缺失、路径大小写不一致。修正方法：优先看失败日志第一处错误，并确认 CI 安装步骤和本地一致。
- **把密钥写进 workflow**：为了省事直接写 token、密码、API key。修正方法：使用 GitHub Secrets，并在日志里避免打印敏感值。
- **自动化做太多太早**：一开始就加部署、缓存、矩阵构建，失败后不知道哪里坏。修正方法：先只保留一个 job、两三个 step，稳定后再扩展。

**7. 进入下一阶段前的自测问题**
当一个 GitHub Actions workflow 失败时，你能不能从日志里指出失败的 job、step、命令和错误原因？

**8. 下一步**
当你能让 CI 自动检查 PR 后，就可以设计更完整的项目维护流程：权限、保护规则、版本发布、文档和团队规范。

### Level 5: 可维护交付流程

**1. 这个阶段要理解什么**
到了这一层，你不只是“会用 Git 和 Actions”，而是能设计一套让项目长期健康运转的流程。你要考虑团队协作、分支保护、自动发布、失败回滚、文档规范和新人上手。重点不是炫技，而是让流程简单、可靠、可解释。

**2. 掌握标准**
- 你可以为一个真实项目设计 Git 分支策略、PR 规则和 CI 检查标准。
- 你可以配置分支保护，让主分支必须通过检查和审查后才能合并。
- 你可以搭建一个简单发布流程，例如打 tag 后自动构建 release。
- 你可以排查常见 CI/CD 失败，并写文档教别人按流程贡献代码。

**3. 核心概念与技能**
- **分支保护规则**：要求 PR、状态检查、审查通过后才能合并，保护主分支质量。
- **版本与标签**：用 tag 标记发布点，例如 `v1.0.0`，让发布历史可追踪。
- **自动发布**：在 CI 通过后自动生成构建产物、Release notes 或部署到目标环境。
- **贡献指南**：`CONTRIBUTING.md` 说明如何建分支、写提交、开 PR、运行测试。
- **故障排查流程**：先定位触发条件、环境、依赖、权限，再改 workflow；不要凭感觉乱试。

**4. 里程碑：证明你准备好了**
把一个仓库整理成“可维护项目”：包含 README、CONTRIBUTING、Issue/PR 模板、CI workflow、分支保护规则，以及至少一个基于 tag 或手动触发的 release workflow。找一个朋友或用另一个账号按文档提交一个 PR，看对方是否能顺利完成流程。

**5. 动手练习 / 小项目**
做一个“项目交付模板仓库”，耗时约 1-2 周的零散时间。选择一个小型代码项目或文档项目，配置完整协作流程：Issue 模板、PR 模板、CI、分支保护、版本 tag、GitHub Release。最后写一份 `CONTRIBUTING.md`，让新人可以在 15 分钟内知道如何贡献。完成结果应该是：任何新 PR 都会自动检查，未通过不能合并，发布流程有清晰记录。

**6. 这个阶段最常犯的错误**
- **流程复杂到没人愿意用**：例如小项目要求多层审批、十几个检查。原因是把企业级流程照搬到小团队。修正方法：只保留能降低真实风险的规则，其他以后再加。
- **CI 失败没人负责**：大家看到红色检查就绕过或忽略。修正方法：规定主分支红灯时优先修复，并在文档里写清排查步骤。
- **发布不可复现**：某次发布靠某个人本地手动打包，之后没人知道怎么重做。修正方法：发布步骤写进 workflow 和文档，用 tag 或手动触发保留记录。
- **权限给得太大**：为了方便给所有 token 写权限、管理员权限。修正方法：Secrets 分环境管理，workflow 权限按最小需要配置。

**7. 进入下一阶段前的自测问题**
如果你离开这个项目两个月，新成员能不能只看仓库文档，就完成一次安全的修改、PR、检查和发布？

**8. 下一步**
接下来你可以围绕真实项目持续优化：减少等待时间、提高测试质量、拆分发布环境，并把流程沉淀成团队标准。

## 🎯 The Road Ahead

Git 和 GitHub 自动化不是一次学完的工具清单，而是一套会随着项目规模升级的工作习惯。你在后面遇到冲突、CI 失败、发布问题时，回到前面的层级补基础是正常的，也是健康的。下一步就从 Level 1 开始：拿一个小项目，认真做 8 次清楚的提交。