AI 时代的单人开发分支范式:轻量 GitHub Flow + 可选 dev

这篇文章适合单人开发但经常使用 AI 辅助写代码的场景。核心思路就四条:

  • main 分支随时能跑能发布(这是底线)
  • 功能开发全在 feature 分支上,小步提交、随时回滚
  • 如果经常让 AI 搞大重构,加个 dev 分支作缓冲
  • AI 生成的代码必须走三连:看 diff → 跑测试 → 小步提交

为什么一个人开发也要讲工作流?

单人开发时使用 AI 工具(如 Claude Code、Cursor 等)会遇到一个问题:AI 太”能干”了。

问题不在于 AI 写不出代码,而在于:

  • 改动范围失控 — 让它修个 bug,它顺手把配置文件、依赖版本、目录结构全”优化”了
  • 隐性行为变化 — 边界条件悄悄变了,但表面上代码看起来更”优雅”
  • 可维护性陷阱 — 生成的代码能跑,但三个月后难以理解

因此需要一套机制来:

AI 是加速器,但工作流是安全带。 需要:

  • 隔离风险 — 试验性改动不能直接污染 main 分支
  • 保持可追溯 — 任何改动都能定位到具体提交,随时可以回滚
  • 固定稳定点 — 永远有一个”能跑的版本”存在(未来的你会感谢现在的你)

两种分支结构,按项目复杂度选一个

方案 A:main + feature/*(简单直接,适合大多数场景)

分支结构:

main (稳定、可运行)
  ├── feature/login
  ├── feature/search
  └── fix/edge-case

适用场景:

  • 项目不需要”集成测试环境”
  • 你希望流程简单、合并少、冲突少
  • 大部分改动都是小型功能或 bug 修复

优点:

  • 历史记录干净
  • 每次合并都明确对应一个功能/修复
  • 心智负担最小

方案 B:main + dev + feature/*(有大量试验时更稳)

分支结构:

main (稳定、可发布)

dev (集成/试验/重构,允许略乱)
  ├── feature/refactor-db
  ├── feature/ai-rewrite
  └── feature/perf-opt

适用场景:

  • 你经常让 AI 做”大手术式重构”
  • 需要多个 feature 组合测试后再发布
  • 希望 main 永远干净,dev 作为缓冲区

优点:

  • dev 承接”乱”和”快”
  • main 承接”稳”和”可交付”
  • 可以在 dev 上折腾到满意再合入 main

我的选择: 这个博客项目用的是方案 B,因为有 Blog Galaxy、Admin 后台、多个工具脚本,经常需要 AI 辅助大规模重构,dev 分支能帮我挡住很多”半成品”。


核心开发流程:三层状态管理

可以把代码的状态理解成三个区间:

1. feature 分支 = 可变更区

写代码、改逻辑、加测试、反复试错,全在这里发生。可以随便折腾。

2. dev 分支 = 可集成区(可选)

多个 feature 组合在一起跑一遍,解决冲突与集成问题。相当于”拼装台”。

3. main 分支 = 可发布区

任何时刻都尽量”能跑、能打包、能交付”。这是红线。

这个三层设计的核心价值就是:风险永远被挡在 main 之外。


日常开发的标准操作流程

1. 开始一个新任务

# 从 dev(或 main)拉新分支
git switch dev         # 方案 A 就换成 main
git pull
git switch -c feature/xxx

分支命名建议:

  • feature/login — 新功能
  • fix/edge-case-null — bug 修复
  • refactor/db-layer — 重构
  • feat/admin-dashboard — 大功能(按模块划分)

命名的意义:未来 git log --oneline 一眼知道改了啥,不用考古。


2. 写代码 + 小步提交

每次提交最好满足:

  • 只做一件事(或一个很小的子步骤)
  • 能通过基本测试/构建(至少不报错)
  • commit message 能描述动机

常用提交信息模板:

feat: add xxx      # 新功能
fix: handle xxx    # 修复 bug
refactor: simplify xxx  # 重构
test: add coverage for xxx  # 测试
chore: bump deps / tweak config  # 杂项

提交节奏示例(以添加 API 为例):

git commit -m "feat: add api endpoint skeleton"
git commit -m "feat: implement core logic"
git commit -m "test: add unit tests"
git commit -m "fix: handle edge case"
git commit -m "refactor: clean up naming"

3. AI 辅助开发的”强制三连”(核心!)

每次让 AI 改完代码,别急着 commit,按这个顺序做:

(1) 看差异

git diff

重点扫这些危险区:

  • package.json / requirements.txt / lockfile — 依赖乱动很要命
  • 配置文件 — CI、编译、路径、环境变量
  • 大范围重命名/移动文件 — 后患无穷
  • 删除大量代码 — 可能误删

(2) 跑最小验证

npm run build  # 或 npm test / npm start

至少跑一次你项目最关键的命令,确保没有低级错误。没测试也行,但你至少启动起来看看日志是否正常。

(3) 小而清楚地提交

如果 AI 改动太大,拆成几次提交(先重构、再功能、再修复、再测试)。

推荐使用:

git add -p  # 分块提交,非常好用

这个命令会让你逐块确认要暂存的改动,强烈推荐。


4. 合并回 dev

git switch dev
git pull
git merge feature/xxx
git push

如果希望保持历史干净,可以用 squash merge(在 GitHub PR 上点一下就行)。


5. 发版:dev 合并回 main

什么时候该 dev → main?

  • ✅ 测试/构建是绿的
  • ✅ 你愿意把当前版本交给”未来的自己”
  • ✅ dev 超前 main 太多了(下面详细解释)

操作命令:

git switch main
git pull
git merge dev
git push

注意: 不要对 dev 分支做 rebase 改历史,哪天工具/脚本/CI 记录对不上,你会骂死自己。


GitHub 上的”ahead by N commits”是什么意思?

当 GitHub 显示:

dev is ahead of main by 10 commits

意思就是:dev 里有 10 个提交,main 还没有。 把它当成”未发布进度条”就行。

本地也能查看:

git fetch origin
git rev-list --count origin/main..dev   # dev 比 main 多几个
git rev-list --count dev..origin/main   # dev 落后 main 几个

单人开发如何用这个指标指导节奏?

一个非常实用的经验阈值:

  • ahead ≤ 5 — 很健康,随时可合
  • 5 < ahead ≤ 20 — 还能接受,但该找个稳定点合回 main 了
  • ahead > 20 — 别拖了,后面合并/回归成本会越来越高

经验建议: dev 超前太多会增加合并冲突的风险,建议控制在 10-15 个提交以内就合并一次。


最小自动化:让 CI 当你的第二双眼睛

你不需要把流程弄得像大厂,但至少要做到一件事:

每次 push/PR 自动跑 lint + tests(或 build)

这样你会获得:

  • AI 引入低级错误,CI 先帮你挡一刀
  • 不会在一个月后才发现”那次改动把构建搞坏了”

GitHub 上建议开:

  • main 分支保护(哪怕你一个人)
  • 要求 CI checks 通过才能合并(防止你手滑)

PR 在单人开发里的作用(不是给别人看的)

一个人也可以开 PR,原因很现实:

  • PR 页面就是”变更审查界面” — 比你在终端翻 diff 舒服
  • PR 描述就是”这次改动的操作说明书” — 三个月后你会感谢这段描述
  • 可以用 checklist 控住质量 — 强制自己走完验证流程

推荐的 PR 模板

标题: feat/fix/refactor: ...

内容:

## 这次改了什么

- ...

## 为什么要改

- ...

## 怎么验证

- [ ] 本地测试通过(写具体命令)
- [ ] CI 通过

## 风险点/回滚

- 风险:...
- 回滚:`git revert <commit>` / 回到 tag `vX.Y.Z`

超实用的”救命按钮”

临时保存现场(切分支/拉更新前)

git stash
# 做完事回来
git stash pop

回滚某次提交(不改历史,最安全)

git revert <commit_hash>

给稳定点打 tag(强烈建议)

git tag v0.1.0
git push --tags

tag 是”你未来逃生用的传送点”。 每次发布或重大功能完成时,给 main 打个 tag,未来出问题可以直接回退。


实战案例:我在这个博客项目上的应用

这个 Misaka Network Blog 项目采用方案 B(main + dev + feature/*),原因:

  • 项目有 Blog Galaxy、Admin 后台、多工具脚本,复杂度较高
  • 经常需要 AI 辅助进行大规模重构
  • 部署到 Cloudflare Pages,main 必须随时可发布

典型工作流示例

场景 1:新增博客功能(如添加阅读时间统计)

# 从 dev 拉新分支
git switch dev
git pull
git switch -c feature/reading-time

# 小步提交
git add src/utils/readingTime.ts
git commit -m "feat: add reading time calculation utility"

git add src/components/PostMeta.astro
git commit -m "feat: display reading time in post metadata"

git add src/pages/blog/[...slug].astro
git commit -m "feat: integrate reading time into blog post page"

# 合并回 dev
git switch dev
git merge feature/reading-time
git push

# 测试 dev 分支没问题后,合并到 main
git switch main
git pull
git merge dev
git tag v1.2.0  # 打标签标记稳定版本
git push --tags
git push

场景 2:AI 辅助重构 Admin 后台

git switch dev
git switch -c refactor/admin-typescript

# AI 生成代码后,强制三连
git diff  # 检查改动范围
npm run admin  # 本地测试
git add -p  # 分块提交

# 第一次提交:类型定义
git commit -m "refactor: add TypeScript types for Admin API"

# 第二次提交:逻辑迁移
git commit -m "refactor: migrate admin-server.js to TypeScript"

# 第三次提交:测试验证
git commit -m "test: verify Admin backend functionality"

git switch dev
git merge refactor/admin-typescript
# 在 dev 上完整测试所有功能后再合入 main

实用的 Git 配置(针对本项目)

.git/config~/.gitconfig 中添加:

[alias]
    # 快速查看分支状态
    st = status -sb

    # 查看 dev 超前 main 多少提交
    ahead = !git rev-list --count origin/main..dev

    # 图形化查看分支历史
    lg = log --graph --oneline --all --decorate

    # 安全的强制推送(仅当远程没有新提交时)
    pushf = push --force-with-lease

    # 快速切换常用分支
    dev = switch dev
    main = switch main

使用示例:

git st              # 快速查看状态
git ahead           # 检查 dev 是否超前太多
git lg              # 可视化查看分支关系

项目专属的提交规范

基于项目模块,建议的 commit prefix:

  • feat(admin): Admin 后台功能
  • feat(galaxy): Blog Galaxy 可视化
  • feat(article): 文章内容/组件
  • fix(build): 构建相关修复
  • refactor(tools): 工具脚本重构
  • docs: 文档更新
  • chore(deps): 依赖更新

示例:

git commit -m "feat(galaxy): add cluster color theme support"
git commit -m "fix(admin): resolve frontmatter parsing for CRLF files"
git commit -m "refactor(tools): move admin and scripts to tools/ directory"

什么时候该 dev → main?

根据项目特点,建议的合并时机:

✅ 应该合并:

  • dev 超前 main 超过 10 个提交
  • 完成一个完整功能(如新增 Blog Galaxy)
  • 修复了影响部署的重大 bug
  • 准备发布新版本到 Cloudflare Pages

❌ 暂缓合并:

  • 某个功能只完成一半
  • 本地测试还没跑通(npm run build 失败)
  • Admin 后台改动没验证完整流程

应急回滚方案

如果 main 被污染了(已 push 到远程):

# 方案 1:回退到上一个稳定 tag
git switch main
git reset --hard v1.1.0
git push --force-with-lease  # 谨慎使用

# 方案 2:revert 错误的合并提交(更安全)
git switch main
git revert -m 1 <merge_commit_hash>
git push

如果 dev 搞乱了:

# 从 main 重新拉出干净的 dev
git branch -D dev
git switch main
git pull
git switch -c dev
git push -f origin dev

最后的总结

这套工作流的核心不是”复杂”,而是控制变化的爆炸半径

你今天省下的 5 分钟提交时间,未来会用 5 小时来还 — 以”考古历史记录找 bug”的形式。

记住三句话:

  1. main 是底线 — 任何时刻能跑、能发、能交付
  2. feature 是实验场 — 允许失败、允许乱,但要可追溯
  3. AI 是加速器,工作流是安全带 — 没有安全带的加速只会让你撞得更惨

附录:推荐阅读