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”的形式。
记住三句话:
- main 是底线 — 任何时刻能跑、能发、能交付
- feature 是实验场 — 允许失败、允许乱,但要可追溯
- AI 是加速器,工作流是安全带 — 没有安全带的加速只会让你撞得更惨
附录:推荐阅读