Developer Tools

Git 工作流指南:分支、合并与团队协作

掌握 Git 分支策略、提交最佳实践、变基与合并的区别,以及专业工程团队所使用的工作流。

8分钟阅读

开发者查看屏幕上的代码

Git 是每个现代软件团队工作流的基石。然而,许多开发者只使用 commitpushpull,忽略了那些让协作开发更顺畅、更少冲突的强大功能。本指南涵盖专业团队所使用的分支策略、提交规范和日常命令。

核心思维模型

Git 是一个由快照(提交)构成的有向无环图。每个提交都指向其父提交。分支只是指向某个提交的具名指针——轻量且创建成本极低。

main:    A → B → C → D
feature:         C → E → F

创建分支不会复制文件,只是新建了一个指针。因此,无论仓库大小,创建分支只需几毫秒。

分支策略

GitHub Flow(简洁,持续交付)

适合频繁部署的团队:

  1. main 始终保持可部署状态
  2. 每次变更都创建一个功能分支
  3. 准备好审查时开启 pull request
  4. 审批通过后合并到 main
  5. 立即部署
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 stuffWIP,你的团队成员会对你感到抓狂。请写得具体一些。

合并 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 — 永远不要在构建失败时请求代码审查
  • 关联 issueCloses #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 的掌握程度会随时间不断积累。理解其核心思维模型,养成良好的提交习惯,你的团队协作效率将会显著提升。