4、分支与合并策略:功能分支管理、合并冲突预防与解决、代码审查与合并请求流程

多项目并行时,文件管理最头疼的问题是什么?我个人的答案是:分支混乱。大家各改各的,最后合到一起时,冲突多到让人崩溃。这一章,我们就来聊聊怎么管好分支、怎么少踩合并的坑。

核心观点:分支策略不是技术问题,是协作契约。契约定好了,冲突自然少。

4.1 功能分支管理:让每个任务都有独立空间

说白了,功能分支就是给每个独立任务一个“隔离区”。你在里面随便改,不影响别人。我见过不少团队直接在 main 或 develop 上开发,结果一个人提交一半,另一个人也提交一半,代码直接乱套。

我个人习惯用 Git Flow 的变体,但会根据项目规模裁剪。小项目用 GitHub Flow 就够了,大项目才需要完整的 Git Flow。

分支命名规范

命名不规范,队友两行泪。我建议统一格式:

  • feature/xxx — 新功能
  • bugfix/xxx — 缺陷修复
  • hotfix/xxx — 紧急修复(直接从 main 拉)
  • release/x.x.x — 发布准备

举个例子:feature/user-login-redesign。一看就知道是做什么的,不用点开代码看。

分支生命周期

分支不是越久越好。我遇到过有人一个分支开了两个月,最后合并时冲突几百个。嗯,这里要注意:功能分支的生命周期建议控制在 3 天以内。超过一周,就要考虑拆分成更小的子任务。

分支类型 来源分支 目标分支 生命周期
feature develop develop ≤ 3 天
bugfix develop develop ≤ 2 天
hotfix main main & develop ≤ 1 天
release develop main & develop ≤ 1 周

4.2 合并冲突预防与解决:别等到冲突了才动手

冲突是必然的,但频率可以控制。你想想看,如果两个人同时改了同一个文件的同一行,Git 也没办法替你决定留谁的。所以,预防比解决更重要。

预防冲突的 4 个习惯

  1. 频繁同步:每天至少从目标分支拉一次最新代码。我习惯早上到公司第一件事就是 git pull --rebase。
  2. 小步提交:每次提交只改一个逻辑单元。别攒了一周才提交,那叫“炸弹”。
  3. 代码所有权:每个模块指定负责人。改之前先沟通,避免两个人同时改同一块。
  4. 使用 .gitattributes:对二进制文件、自动生成文件设置合并策略,比如 *.pbxproj merge=union。
小技巧:我常用 git diff --check 在提交前检查是否有空白冲突。这能避免很多无意义的冲突。

解决冲突的标准流程

真遇到冲突了,别慌。按步骤来:

  1. 运行 git status 确认哪些文件冲突
  2. 打开冲突文件,搜索 <<<<<<< 标记
  3. 手动选择保留哪部分代码,或重写
  4. 删除冲突标记
  5. 运行 git add 标记已解决
  6. 运行 git commit 完成合并
# 示例:解决冲突后的提交信息
git commit -m "Merge branch 'feature/user-login' into develop

解决 user.js 第 45-52 行冲突
保留两边的验证逻辑,合并为统一校验函数"
避坑指南:我曾经在解决冲突时,不小心删掉了队友刚加的异常处理逻辑。那次上线后直接出了 P0 故障。后来我养成了一个习惯:解决冲突后,一定要跑一遍完整的单元测试,确保两边逻辑都还在。

4.3 代码审查与合并请求流程:质量守门员

合并请求(Pull Request / Merge Request)不只是“把代码合进去”的动作,它是一次质量审查。我个人认为,没有经过审查的代码,不应该进入主分支。

合并请求的标准流程

我建议的流程是这样的:

  1. 开发者从 develop 拉出功能分支
  2. 开发完成后,推送分支到远程仓库
  3. 创建合并请求,指定审查者
  4. 审查者进行代码审查,提出修改意见
  5. 开发者根据意见修改,更新分支
  6. 审查者确认无误后,批准合并
  7. 合并到 develop,删除功能分支

代码审查清单

审查不是随便看看。我整理了一份清单,每次审查都对照着来:

审查项 检查内容
功能正确性 代码是否实现了需求?边界情况是否处理?
代码风格 是否符合团队规范?命名是否清晰?
安全性 是否有 SQL 注入、XSS 等风险?
性能 是否有不必要的循环、重复查询?
可维护性 是否有注释?逻辑是否过于复杂?
测试覆盖 是否有单元测试?测试是否通过?

合并策略选择

合并时,有三种常见策略。我根据场景选择:

  • Merge Commit:保留完整历史,适合大功能合并
  • Squash and Merge:将多个提交压缩成一个,适合小功能或修复
  • Rebase and Merge:线性历史,适合追求整洁日志的团队

我个人偏好 Squash and Merge。为什么?因为功能分支上的提交往往很零碎,“fix typo”、“add debug log”这种提交没必要留在主分支历史里。压缩成一个提交,历史清晰多了。

经验之谈:合并请求的描述一定要写清楚“做了什么”和“为什么这么做”。我见过太多只写“fix bug”的 PR,审查者根本不知道改了啥。好的描述能节省审查者 50% 的时间。

4.4 本章知识体系

下面这张图,把分支与合并策略的核心逻辑串起来了。你可以把它贴在团队的白板上。

分支与合并策略知识体系 分支与合并策略知识体系 功能分支管理 合并冲突预防与解决 代码审查与合并请求 命名规范 生命周期 频繁同步 小步提交 审查清单 合并策略 核心原则 分支策略是协作契约 → 预防冲突比解决冲突更重要 → 审查是质量守门员 创建分支 开发提交 创建 PR 代码审查 合并 & 删除 不通过,退回修改

这张图展示了三个核心模块的关联:功能分支管理是基础,合并冲突预防是保障,代码审查是质量关卡。三者缺一不可。

团队落地建议:刚开始推行分支策略时,别一下子全上。先定好命名规范和 PR 流程,跑两周再引入审查清单。步子太大,容易扯着。