Git 工作流指南:分支、合并与团队协作
掌握 Git 分支策略、提交最佳实践、变基与合并的区别,以及专业工程团队所使用的工作流。
Git 是每个现代软件团队工作流的基石。然而,许多开发者只使用 commit、push 和 pull,忽略了那些让协作开发更顺畅、更少冲突的强大功能。本指南涵盖专业团队所使用的分支策略、提交规范和日常命令。
核心思维模型
Git 是一个由快照(提交)构成的有向无环图。每个提交都指向其父提交。分支只是指向某个提交的具名指针——轻量且创建成本极低。
main: A → B → C → D
feature: C → E → F
创建分支不会复制文件,只是新建了一个指针。因此,无论仓库大小,创建分支只需几毫秒。
分支策略
GitHub Flow(简洁,持续交付)
适合频繁部署的团队:
main始终保持可部署状态- 每次变更都创建一个功能分支
- 准备好审查时开启 pull request
- 审批通过后合并到
main - 立即部署
git checkout -b feature/add-user-auth
# ... 进行更改 ...
git push origin feature/add-user-auth
# 开启 PR → 审查 → 合并 → 部署
Git Flow(结构化发布)
适合有版本化发布需求的产品(应用、库):
main— 仅存放生产代码develop— 集成分支feature/*— 新功能(从develop创建)release/*— 发布准备(从develop创建)hotfix/*— 紧急生产修复(从main创建)
结构更严谨,但增加了额外开销。除非确实需要管理并行发布,否则建议使用 GitHub Flow。
主干开发(Trunk-Based Development)
开发者直接向 main 提交(或使用生命周期不超过 1 天的短期分支)。通过功能开关控制用户所见的内容。需要强大的 CI/CD 和测试覆盖率。Google、Facebook 及高速迭代团队均采用此模式。
编写优质的提交信息
提交信息是写给未来的自己(以及队友)的一封信。遵循 Conventional Commits 格式:
<type>(<scope>): <简短摘要>
<可选正文 — 写什么和为什么,而非怎么做>
<可选页脚 — 破坏性变更、issue 引用>
类型说明:
feat— 新功能fix— Bug 修复docs— 仅文档变更refactor— 既不修复 Bug 也不新增功能的代码重构test— 新增或修复测试chore— 构建流程、依赖、工具链
示例:
feat(auth): add JWT refresh token rotation
Implements sliding session windows using refresh token rotation.
Previous tokens are invalidated on use to detect theft.
Closes #142
fix(api): return 404 instead of 500 for missing user
The /users/:id endpoint was throwing an unhandled exception when
the user didn't exist. Now returns a proper 404 with error message.
经验之谈: 如果你的提交信息是
fix stuff或WIP,你的团队成员会对你感到抓狂。请写得具体一些。
合并 vs. 变基
合并(Merge)
git checkout main
git merge feature/my-feature
会创建一个合并提交,将两个分支连接在一起。保留完整历史——可以清楚地看到分支何时分叉、何时合并。
A → B → C → M (合并提交)
↑ ↑
E → F (功能分支)
适用场景:集成长期运行的分支、在历史记录中保留上下文信息。
变基(Rebase)
git checkout feature/my-feature
git rebase main
将你的提交重新应用到目标分支之上,形成线性历史——看起来就像功能是在最新的 main 基础上开发的。
变基前: A → B → C (main)
↑
D → E (feature, 基于 B)
变基后: A → B → C → D' → E' (feature 变基到 C 之上)
适用场景:在开启 PR 前整理本地提交、保持功能分支与最新代码同步。
黄金法则: 永远不要对已推送到共享分支的提交执行变基。变基会重写历史——这会破坏其他人的本地分支。
交互式变基:整理历史记录
在开启 PR 之前,将杂乱的临时提交进行压缩和整理:
git rebase -i HEAD~4 # 交互式编辑最近 4 次提交
交互式编辑器中的选项:
pick— 保留该提交squash— 合并到上一个提交,合并提交信息fixup— 合并到上一个提交,丢弃提交信息reword— 保留变更,修改提交信息drop— 完全删除该提交
处理冲突
当两个分支修改了同一行代码时,就会发生冲突。Git 会标记如下:
<<<<<<< HEAD(你的分支)
const timeout = 5000;
=======
const timeout = 3000;
>>>>>>> feature/update-timeouts
编辑文件至正确状态(删除冲突标记),然后执行:
git add src/config.ts
git merge --continue # 或 git rebase --continue
预防胜于治疗:
- 频繁从
main拉取代码,保持分支短暂存活 - 在修改同一文件时与队友提前沟通
- 保持 PR 精简——PR 越大,冲突越多,审查难度也越大
每日必备命令
# 开始一个新功能
git checkout -b feature/my-feature
# 暂存特定改动(而非整个文件)
git add -p
# 查看未暂存的变更
git diff
# 查看已暂存的变更
git diff --staged
# 修改最后一次提交(推送之前)
git commit --amend --no-edit
# 临时保存未提交的工作
git stash
git stash pop
# 找出引入 Bug 的提交(二分查找)
git bisect start
git bisect bad # 当前提交有问题
git bisect good v1.2.0 # 最后一个已知正常的提交
# 恢复已删除的分支或丢失的提交
git reflog
# 以图形方式查看分支结构
git log --oneline --graph --all
Pull Request 最佳实践
一个好的 PR 应该:
- 只做一件事 — 让审查者能够理解完整的变更内容
- 有清晰的描述 — 说明改了什么、为什么改、如何测试
- 体量精简 — 粗略目标是 diff 不超过 400 行
- 通过 CI — 永远不要在构建失败时请求代码审查
- 关联 issue —
Closes #42会在合并时自动关闭对应 issue
使用我们的 README Generator 为你的代码变更同步生成规范文档。
.gitignore 必备内容
务必将以下内容添加到 .gitignore:
# 环境变量
.env
.env.local
.env.*.local
# 依赖
node_modules/
vendor/
# 构建输出
dist/
build/
.next/
# 系统文件
.DS_Store
Thumbs.db
# 编辑器文件
.vscode/settings.json
.idea/
*.swp
在 gitignore.io 生成适合你项目的 .gitignore——它支持数百种语言和工具。
Git 的掌握程度会随时间不断积累。理解其核心思维模型,养成良好的提交习惯,你的团队协作效率将会显著提升。