Git Rebase 最佳实践

本文档用于说明在多人协作开发中,如何正确使用 git rebase 保持提交历史清晰、减少无意义的 merge commit,并降低多人并行开发时的集成成本。

本文特别适用于如下协作模式:

  • master 作为主干分支
  • 某个完整需求从 master 拉出功能总分支,例如 feature/2026001
  • 每位开发人员从 feature/2026001 拉出个人开发分支,例如 feature/2026001-zhangsan
  • 每个阶段开发完成后,先整理个人提交,再将个人分支无额外 merge commit 地合回功能总分支

核心原则

1. rebase 重放的是"当前分支"的提交

执行:

bash 复制代码
git checkout feature/2026001-zhangsan
git rebase feature/2026001

含义是:

  • feature/2026001 的最新提交作为新的 base
  • feature/2026001-zhangsan 独有的提交,重新应用到这个最新 base 之后

不是把 feature/2026001 的提交搬到 feature/2026001-zhangsan 后面,而是把当前分支自己的提交重放到目标分支之后。

2. 想让谁接到别人后面,就先 checkout 谁

如果你的目标是:

  • feature/2026001-zhangsan 接到 feature/2026001 的最新代码后面

那就应该:

bash 复制代码
git checkout feature/2026001-zhangsan
git rebase feature/2026001

3. rebase 适合整理个人分支,不适合重写公共分支历史

推荐:

  • 在自己的开发分支上使用 rebase
  • 在提交合并请求前整理自己的提交历史

不推荐:

  • 随意对多人共用、已经广泛同步的公共分支执行会改写历史的 rebase

4. 目标是线性历史,而不是制造"整洁但危险"的历史

线性历史的意义在于:

  • 更容易看清某个功能是如何逐步进入主线的
  • 更容易排查问题和回溯提交
  • 避免大量无意义的 merge commit 干扰阅读

但前提是:

  • 团队成员明确知道哪些分支允许 rebase
  • rebase 后若分支已推送远程,需要谨慎处理推送方式

什么时候应该用 rebase

适合使用 rebase 的场景:

  • 个人开发分支需要同步功能总分支最新代码
  • 个人开发分支准备合回功能总分支前,希望整理提交历史
  • 希望避免产生额外 merge commit
  • 希望最终提交链清晰、线性

不建议优先使用 rebase 的场景:

  • 公共分支已经被多人基于其继续开发
  • 团队成员不熟悉冲突处理流程
  • 已推送到远程且被他人依赖的历史不适合改写

推荐工作流

1. 从 master 拉出功能总分支

bash 复制代码
git checkout master
git pull
git checkout -b feature/2026001

2. 每位开发人员从功能总分支拉出自己的开发分支

bash 复制代码
git checkout feature/2026001
git pull
git checkout -b feature/2026001-zhangsan

3. 在个人开发分支上开发

开发过程中可以有多个临时提交,例如:

bash 复制代码
git commit -m "wip: 完成第一部分"
git commit -m "fix: 修正样式"
git commit -m "update: 补充接口逻辑"

4. 一个阶段完成后,先整理提交

目标是将这一阶段的提交压缩成一个清晰、可理解的提交。

常见做法:

bash 复制代码
git rebase -i HEAD~3

然后将多个临时提交整理成一个有意义的提交,例如:

text 复制代码
feat: 完成第一阶段xxxx功能开发

5. 将个人分支 rebase 到最新的功能总分支

bash 复制代码
git checkout feature/2026001-zhangsan
git fetch origin
git rebase origin/feature/2026001

如果本地就是最新的 feature/2026001,也可以:

bash 复制代码
git rebase feature/2026001

6. 若出现冲突,解决后继续

处理步骤:

bash 复制代码
git status

手动解决冲突后:

bash 复制代码
git add .
git rebase --continue

若仍有后续冲突,则重复上述步骤。

如果要放弃本次 rebase:

bash 复制代码
git rebase --abort

7. rebase 完成后,将个人分支无额外 commit 地合回功能总分支

bash 复制代码
git checkout feature/2026001
git merge --ff-only feature/2026001-zhangsan

这样做的前提是:

  • 个人分支已经完成 rebase,位于功能总分支最新提交之后

此时 --ff-only 会执行 fast-forward:

  • 不产生新的 merge commit
  • 仅让 feature/2026001 指针前移到个人分支的最新提交

8. 多个开发者依次重复该流程

每位开发者都遵循:

  1. 整理个人提交
  2. rebase 最新的 feature/2026001
  3. 解决冲突
  4. 使用 merge --ff-only 合回 feature/2026001

最终形成线性、可读的功能分支历史。

9. 功能总分支开发完成后,提交合并请求到 master

此时 feature/2026001 的历史通常已经较为整洁,可以发起 MR / PR。


典型流程图

以下流程图基于你的团队协作场景。

flowchart TD A[master] --> B[拉出功能总分支
feature/2026001] B --> C1[张三拉出个人分支
feature/2026001-zhangsan] B --> C2[李四拉出个人分支
feature/2026001-lisi] B --> C3[王五拉出个人分支
feature/2026001-wangwu] C1 --> D1[张三开发一阶段
产生多个临时 commit] D1 --> E1[整理提交
squash 成 1 个阶段 commit] E1 --> F1[rebase feature/2026001
解决冲突] F1 --> G1[merge --ff-only 回 feature/2026001
不产生新的 merge commit] C2 --> D2[李四开发一阶段
产生多个临时 commit] D2 --> E2[整理提交
squash 成 1 个阶段 commit] E2 --> F2[rebase 最新 feature/2026001
解决冲突] F2 --> G2[merge --ff-only 回 feature/2026001
不产生新的 merge commit] C3 --> D3[王五开发一阶段
产生多个临时 commit] D3 --> E3[整理提交
squash 成 1 个阶段 commit] E3 --> F3[rebase 最新 feature/2026001
解决冲突] F3 --> G3[merge --ff-only 回 feature/2026001
不产生新的 merge commit] G1 --> H[feature/2026001 持续累计所有阶段成果] G2 --> H G3 --> H H --> I[功能开发完成] I --> J[feature/2026001 提交 MR 到 master]

提交历史示意图

初始状态

text 复制代码
master
  A0 --- A1
           \
            feature/2026001
              F0

张三从功能总分支拉出个人分支

text 复制代码
master
  A0 --- A1
           \
            feature/2026001
              F0
               \
                feature/2026001-zhangsan
                  Z1 --- Z2 --- Z3

张三整理提交后

text 复制代码
master
  A0 --- A1
           \
            feature/2026001
              F0
               \
                feature/2026001-zhangsan
                  Z1'

此时功能总分支已有其他人提交的新内容

text 复制代码
master
  A0 --- A1
           \
            feature/2026001
              F0 --- F1 --- F2
               \
                feature/2026001-zhangsan
                  Z1'

张三执行 git checkout feature/2026001-zhangsan && git rebase feature/2026001

rebase 后:

text 复制代码
master
  A0 --- A1
           \
            feature/2026001
              F0 --- F1 --- F2
                            \
                             feature/2026001-zhangsan
                               Z1''

说明:

  • F1F2 是功能总分支的新提交
  • Z1' 是张三整理后的阶段提交
  • Z1'' 是 rebase 后的新提交,内容语义相同,但 SHA 改变了

张三执行 git checkout feature/2026001 && git merge --ff-only feature/2026001-zhangsan

text 复制代码
master
  A0 --- A1
           \
            feature/2026001
              F0 --- F1 --- F2 --- Z1''

结果:

  • 无新的 merge commit
  • 张三的改动被线性接到了功能总分支后面

后续李四、王五依次重复同样流程。


冲突处理最佳实践

1. 冲突不是按目标分支的 commit 数量处理

例如:

  • feature/2026001 比分叉点多了 5 个 commit
  • feature/2026001-zhangsan 只有 1 个阶段 commit

执行:

bash 复制代码
git checkout feature/2026001-zhangsan
git rebase feature/2026001

通常只需要处理:

  • 张三这 1 个阶段 commit 与 feature/2026001 最新代码之间的冲突

不是分别对 feature/2026001 的 5 个 commit 逐个处理。

2. 尽量先 squash,再 rebase

原因:

  • 能显著降低 rebase 冲突次数
  • 提高冲突解决效率
  • 让功能总分支历史更清晰

3. 冲突时先判断"保留谁的最新语义"

解决冲突不要机械地保留"我的代码"或"别人的代码",而应判断:

  • 功能总分支是否已有新规范、新接口、新字段
  • 自己的提交是否基于旧结构编写
  • 最终保留的代码是否同时满足当前主线和当前需求

4. 冲突解决后及时运行验证

建议在 rebase --continue 之前或之后进行基本验证:

bash 复制代码
npm run lint
npm run test

至少应确认:

  • 编译通过
  • 关键页面可运行
  • 关键交互未回退

常用命令速查表

查看当前状态

bash 复制代码
git status
git branch
git log --oneline --graph --decorate -20

用途:

  • 查看当前所在分支
  • 查看工作区是否干净
  • 快速理解最近提交关系

从主干拉出功能总分支

bash 复制代码
git checkout master
git pull
git checkout -b feature/2026001

从功能总分支拉出个人开发分支

bash 复制代码
git checkout feature/2026001
git pull
git checkout -b feature/2026001-zhangsan

将最近多个临时提交整理成一个提交

bash 复制代码
git rebase -i HEAD~3

常见用法:

  • 第一条保留 pick
  • 后续条目改成 squashfixup

同步远程最新分支信息

bash 复制代码
git fetch origin

将个人分支 rebase 到最新功能总分支

bash 复制代码
git checkout feature/2026001-zhangsan
git rebase origin/feature/2026001

如果本地 feature/2026001 已经是最新,也可以:

bash 复制代码
git rebase feature/2026001

rebase 过程中处理冲突后继续

bash 复制代码
git status
git add .
git rebase --continue

放弃本次 rebase

bash 复制代码
git rebase --abort

跳过当前出问题的 commit

仅在你明确知道该 commit 可以不要时使用:

bash 复制代码
git rebase --skip

将个人分支无新 commit 地合回功能总分支

bash 复制代码
git checkout feature/2026001
git merge --ff-only feature/2026001-zhangsan

说明:

  • 成功则不会产生新的 merge commit
  • 失败说明当前无法 fast-forward,需要先检查是否 rebase 到最新总分支

查看两个分支的提交差异

bash 复制代码
git log --oneline feature/2026001..feature/2026001-zhangsan
git log --oneline feature/2026001-zhangsan..feature/2026001

用途:

  • 第一条查看"个人分支比功能总分支多哪些提交"
  • 第二条查看"功能总分支比个人分支多哪些提交"

查看分支内容差异

bash 复制代码
git diff feature/2026001...feature/2026001-zhangsan

用途:

  • 查看两个分支从共同祖先开始,到当前为止的代码差异

rebase 完成后推送远程

如果该分支历史已被 rebase 改写,通常需要:

bash 复制代码
git push --force-with-lease

不要直接使用:

bash 复制代码
git push --force

提交合并请求前的常见检查

bash 复制代码
git status
git log --oneline --graph --decorate -20
npm run lint
npm run test

推荐命令模板

个人阶段完成后的标准流程

bash 复制代码
# 1. 切到个人分支
git checkout feature/2026001-zhangsan

# 2. 整理这一阶段的提交
git rebase -i HEAD~N

# 3. 获取远程最新代码
git fetch origin

# 4. 基于最新功能总分支 rebase
git rebase origin/feature/2026001

# 5. 若冲突,解决后继续
git add .
git rebase --continue

# 6. rebase 完成后切回功能总分支
git checkout feature/2026001

# 7. 快进合并,不产生新的 merge commit
git merge --ff-only feature/2026001-zhangsan

团队约定建议

建议团队统一约定以下规则:

  • 个人分支允许 rebase
  • 功能总分支尽量只接受整理后的阶段提交
  • 合回功能总分支时优先使用 merge --ff-only
  • 每一阶段结束前先 squash,再 rebase
  • 已被多人依赖的公共分支不要随意改写历史
  • rebase 结束后如需强推,优先使用:
bash 复制代码
git push --force-with-lease

不要直接使用:

bash 复制代码
git push --force

常见误区

误区 1:git rebase X 是把 X 挪到当前分支后面

错误。

正确理解是:

  • git rebase X 会把当前分支自己的提交 重放到 X 后面

误区 2:目标分支有多少个新提交,就要解决多少次冲突

错误。

rebase 的冲突次数更直接取决于:

  • 当前分支有多少个需要被重放的提交

误区 3:merge 一定比 rebase 更"安全"

不完全正确。

更准确地说:

  • merge 更不改历史
  • rebase 更适合整理个人分支历史

关键不是哪个绝对更安全,而是:

  • 是否在正确的分支上使用了正确的方法

一句话总结

在多人协作的功能分支开发中,推荐采用:

  • 个人分支开发
  • 阶段完成先 squash
  • 再 rebase 功能总分支
  • 最后使用 merge --ff-only 合回

这样可以同时获得:

  • 清晰的线性历史
  • 较低的冲突处理成本
  • 没有额外的 merge commit
  • 更适合后期 review、回滚和问题排查的提交链
相关推荐
Ferries1 小时前
《从前端到 Agent》系列|02:应用层-提示词工程 (Prompt Engineering)
前端·人工智能·深度学习
Awu12271 小时前
⚡Pretext: 无 DOM 布局回流的快速文本测量库
前端
前端Hardy2 小时前
别再手写代码了!2026 前端 5 个 AI 杀招,直接解放 80% 重复劳动(附工具+步骤)
前端·javascript·面试
SuperEugene2 小时前
Element Plus/VXE-Table UI 组件库规范:统一用法实战,避开样式冲突与维护混乱|工程化与协作规范篇
前端·javascript·vue.js·ui·前端框架·element plus·vxetable
前端Hardy2 小时前
前端工程师必备的 10 个 AI 万能提示词(Prompt),复制直接用,效率再翻倍!
前端·javascript·面试
BioRunYiXue2 小时前
Nature Methods:CellVoyager 自主 AI 智能体开启生物数据分析新时代
大数据·开发语言·前端·javascript·人工智能·数据挖掘·数据分析
ノBye~2 小时前
Docker Compose+Jenkins自动化部署全流程
git·docker·jenkins
再玉米地里吃过亏3 小时前
ONENET平台API鉴权错误
前端
网络点点滴3 小时前
Vue3中Suspense的使用
前端·javascript·vue.js