Git 团队协作工作流实战手册
前言
在大三的课程项目和实习中,我从"一个人写代码"过渡到了"多人协作开发"。Git 不再只是 commit 和 push,分支策略、代码审查、冲突解决——这些才是真正考验协作能力的地方。这篇文章总结我在实际项目中积累的 Git 工作流经验。
为什么要用分支策略
没有分支策略的团队就像没有交通规则的十字路口——迟早会撞车。一个好的分支策略能带来:
- 并行开发:多人同时开发不同功能,互不干扰
- 版本可控:随时知道哪个版本对应哪些功能
- 快速修复:线上出 Bug 能不动正在开发的功能就修复
- 可追溯性:每个功能都有清晰的历史记录
Git Flow:经典但偏重
master ──────●────────────●────────────●──→ 生产版本
\ / /
develop ──────●──●──●──●────●──●────●──→ 开发主干
\ / \ / \ /
feature/A ─────●──● \ /
\ /
feature/B ────────────────●──●──●
\
hotfix ───────────────────────────●──→ 紧急修复
Git Flow 定义了五种分支:
| 分支 | 用途 | 生命周期 |
|---|---|---|
master/main |
生产代码 | 永久 |
develop |
开发主干 | 永久 |
feature/* |
功能开发 | 功能合并后删除 |
release/* |
版本发布准备 | 发布后删除 |
hotfix/* |
紧急修复 | 修复后删除 |
适用场景:有固定发布周期的传统项目,版本号明确。
缺点:分支太多,对小型团队来说过于繁重。
Trunk-Based Development:轻量高效
main ──●──●──●───●──●──●──→ 主干
\ / / / /
feat/A ──● / / /
feat/B ───────● / /
feat/C ──────────● /
fix/D ──────────────●
核心理念:所有人都直接在 main 上工作,短期分支快速合并。
规则很简单:
- 分支生命周期不超过 1-2 天
- 使用 Feature Flag 控制功能开关
- 高频提交、高频合并
- CI/CD 确保每次合并都是可部署的
适用场景:持续交付团队、中小型项目。我个人更倾向于这种方式。
我们团队的实际工作流
综合 Git Flow 和 Trunk-Based 的优点,我们的工作流:
main ←──────── PR ←── feat/user-auth
↑ ↑
│ │
└── 部署到生产 └── 开发中
分支命名规范
feat/user-login # 新功能
fix/order-timeout # Bug 修复
refactor/payment-module # 重构
docs/api-documentation # 文档
chore/update-deps # 杂项(依赖更新等)
标准操作流程
# 1. 从最新的 main 创建功能分支
git checkout main
git pull origin main
git checkout -b feat/user-profile
# 2. 开发过程中频繁提交
git add .
git commit -m "feat: add user profile page"
# 3. 合并 main 的最新代码(解决冲突)
git checkout main && git pull
git checkout feat/user-profile
git merge main
# 4. 推送并创建 Pull Request
git push origin feat/user-profile
# 然后在 GitHub/GitLab 上创建 PR
Commit Message 规范
好的提交信息是给自己和团队的一份礼物。我们采用 Conventional Commits 规范:
<type>(<scope>): <subject>
<body>
<footer>
Type 类型
| Type | 说明 | 示例 |
|---|---|---|
feat |
新功能 | feat: add user avatar upload |
fix |
Bug 修复 | fix: resolve order timeout on high load |
refactor |
重构 | refactor: extract payment service |
docs |
文档 | docs: update API documentation |
style |
格式 | style: format code with prettier |
test |
测试 | test: add unit tests for auth module |
chore |
杂项 | chore: update dependencies |
perf |
性能优化 | perf: optimize image compression |
好的提交 vs 坏的提交
❌ 修了个bug
❌ update
❌ 改了点什么
❌ WIP
✅ fix: resolve null pointer when user avatar is empty
✅ feat(auth): add JWT token refresh mechanism
✅ refactor: extract validation logic to middleware
一个关键原则:每个 commit 只做一件事。如果一个 commit 消息里有"和",考虑拆成两个。
Pull Request / Merge Request 最佳实践
PR 应该包含什么
一个合格的 PR 应该包含:
- 清晰的标题:用 Conventional Commits 格式
- 描述:
- 做了什么(What)
- 为什么这么做(Why)
- 怎么做的——技术方案简述(How)
- 测试情况
- 截图或演示(前端变动)
- 关联 Issue:
Closes #123
## 做了什么
实现了用户头像上传功能,支持裁剪和压缩。
## 为什么
用户反馈缺少个性化设置,头像是最基本的需求。
## 技术方案
- 前端使用 cropper.js 实现裁剪
- 后端使用 sharp 库压缩图片
- 上传至 OSS,数据库存储 URL
## 测试
- 上传 JPG/PNG/WebP 各一张,均正常
- 超过 10MB 的文件正确拒绝
- 未登录上传返回 401
## 截图

Closes #42
Code Review 礼仪
Reviewer(审查者):
- 关注逻辑和设计,而非代码风格(让 Linter 处理)
- 区分"必须改"和"建议改"
- 提出问题而非指令:"这里用递归会不会有栈溢出风险?"
Author(作者):
- PR 尽量小(控制在 400 行以内)
- 每个评论都要回复(哪怕只是 )
- 被指出问题不要 defensive——这是学习机会
Merge 策略选择
| 策略 | 效果 | 适合场景 |
|---|---|---|
| Merge Commit | 保留完整分支历史 | 需要追溯每个功能的场景 |
| Squash Merge | 将所有 commit 合并为一个 | 功能分支 commit 较乱时 |
| Rebase Merge | 线性历史,无 merge commit | 追求干净历史的团队 |
我们团队的选择:功能分支用 Squash Merge,hotfix 用 Rebase Merge。
# Squash Merge 效果
Before: feat: wip → feat: continue → feat: done
After: feat: add user avatar upload (1 commit)
# Rebase Merge 效果
Before: main 和 feat 分支交错
After: 一条干净的线
冲突解决实战
冲突是协作的自然产物,不应该害怕它。
# 遇到冲突时
git merge main
# CONFLICT in src/user/controller.js
# 查看冲突文件
git status
# 解决冲突(手动编辑文件,删除 <<<<<< ==== >>>>>> 标记)
# 标记已解决
git add src/user/controller.js
git commit -m "merge: resolve conflict with main"
实用技巧:
# 使用可视化工具解决冲突
git mergetool
# 完全接受某一方的版本
git checkout --theirs src/user/controller.js # 接受 main 分支的
git checkout --ours src/user/controller.js # 保留自己的
常见失误与补救
1. 不小心 commit 到错误的分支
# 把最近的 commit 移到正确的分支
git checkout correct-branch
git cherry-pick <commit-hash>
git checkout wrong-branch
git reset --hard HEAD~1
2. commit 信息写错了
# 修改最近一次 commit 信息
git commit --amend -m "正确的信息"
3. 不小心 push 了不该 push 的文件
# 从 Git 历史中移除敏感文件
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch config/secrets.json" \
--prune-empty --tag-name-filter cat -- --all
4. 回退已经 push 的 commit
# 创建反向 commit(安全)
git revert <commit-hash>
git push
# 强制覆盖(危险!只在个人分支使用)
git reset --hard <commit-hash>
git push --force
Git Alias 提效
在 ~/.gitconfig 中配置别名:
[alias]
co = checkout
br = branch
ci = commit
st = status
lg = log --oneline --graph --all --decorate
unstage = reset HEAD --
last = log -1 HEAD
undo = reset --soft HEAD~1
prune-local = !git branch --merged | grep -v '\\*\\|main\\|master' | xargs -r git branch -d
总结
Git 不只是"保存代码"的工具,它是团队协作的语言。总结几个核心原则:
- 小步提交:每个 commit 原子化,方便回退和审查
- 规范命名:分支名、commit 信息都遵循约定
- 及时同步:经常 merge main,避免积压大量冲突
- Code Review:把它当作学习机会,不是找茬
- 善用工具:
git lg查看历史、git stash暂存临时代码、git bisect定位 Bug
这些经验来自大三一年里 5 个以上实际项目的协作实践。Git 从"必须用的工具"变成了"帮我省事的工具"——这个转变,需要的就是刻意练习和团队约定。
本文基于 ERP 系统、灵山胜境等多个团队项目的实际 Git 工作流经验总结。

浙公网安备 33010602011771号