一次 Git Rebase 事故,让我彻底明白 Rebase 和 Merge 的区别

前言

事情的起因是这样的: 上周我在项目里用 git rebase 整理分支,结果把同事的提交"消失"了,虽然最后救回来了,但大家吓出一身冷汗。 这次事件让我彻底搞清楚了 rebasemerge 的区别,以及它们各自适合的场景。


一、先还原"事故现场"

假设我们有这样一个场景:

  • 你在 feature 分支上开发新功能
  • 同事在 main 分支上修了一个紧急 bug

提交历史长这样:

text 复制代码
main:    A --- B --- C (bug 修复)
           \
feature:    D --- E (你的新功能)

你用 git rebase main

bash 复制代码
git checkout feature
git rebase main

这会变成这样:

text 复制代码
main:    A --- B --- C
                        \
feature:                 D' --- E'

看起来很整齐,但如果你本地的 feature 没有先拉同事的最新提交,或者在 rebase 过程里解决冲突时手滑丢掉了同事的改动,push 上去时可能直接覆盖掉远程历史,让同事的代码凭空消失

这就是我当时踩的坑。


二、rebase 和 merge 到底有什么区别?

1. git merge ------ 历史完整,简单安全

  • 会创建一个新的 merge commit
  • 不会改动已有提交历史
  • 适合多人协作、要保留所有分支的提交轨迹

示例:

bash 复制代码
git checkout feature
git merge main

结果:

text 复制代码
A --- B --- C ------ M (merge commit)
 \              /
  D --- E -----

特点:

  • 提交历史可能"分叉"比较多,但安全
  • 解决冲突只发生一次

2. git rebase ------ 历史干净,但会改动历史

  • 会把你当前分支的提交"搬到"目标分支的最新提交之后
  • 会生成新的提交 ID(即使内容相同)
  • 适合自己本地分支整理历史,不要在公共分支上随意用

示例:

bash 复制代码
git checkout feature
git rebase main

结果:

text 复制代码
A --- B --- C --- D' --- E'

特点:

  • 历史像一条直线,干净美观
  • 改动的是提交历史,如果已经 push 过且别人基于它开发,容易引发冲突甚至丢代码

三、各自的安全使用场景

场景 推荐方式 原因
本地分支开发,还没 push 给别人 rebase 整理历史,方便以后合并
拉取远程更新并保持历史干净 pull --rebase 避免多余的 merge commit
已经 push,且有同事基于它开发 merge 避免改写历史导致冲突
大型团队的主分支合并 merge 保留历史,方便追溯
个人项目或短期功能分支 rebase 历史整洁,美观

四、如何避免 rebase 导致代码丢失?

  1. 不要在公共分支上 rebase (例如 maindev

  2. 如果必须 rebase,先确保拉取远程最新代码:

    bash 复制代码
    git fetch origin
    git rebase origin/main
  3. 解决冲突时仔细检查改动,确保同事的提交没有被覆盖

  4. rebase 失败或出错时,可以用:

    bash 复制代码
    git rebase --abort
  5. 养成推送前检查差异的习惯:

    bash 复制代码
    git log --oneline --graph --decorate
    git diff

五、我的经验总结

  • merge 像是在账本上追加记录,不动旧账,安全可靠
  • rebase 像是改账本,让账单更漂亮,但改错了可能账就乱了
  • 团队协作中,公共分支用 merge,本地分支用 rebase,基本就能避免大部分事故

结语

写在最后,这次的事故让我明白: Git 是个很宽容的工具,但对历史的操作必须敬畏。 代码丢失不可怕,可怕的是我们连为什么丢都不知道。 理解 mergerebase 的底层行为,才能在团队里安全高效地用好它们。

相关推荐
似水流年流不尽思念2 分钟前
常见的排序算法有哪些?它们的平均时间复杂度是多少?
后端·算法
孟永峰_Java1 小时前
MySQL 组合IN查询:你的索引为什么罢工了?
后端
ruokkk1 小时前
一个困扰我多年的Session超时Bug,被我的新AI搭档半天搞定了
javascript·后端·架构
楽码1 小时前
端到端应用Hmac加密
服务器·后端·算法
孟永峰_Java1 小时前
Java程序员的周五:代码没写完,但我的心已经放假了!
后端
uhakadotcom1 小时前
Flink有python的SDK入门教程
后端·面试·github
kong@react1 小时前
spring boot配置es
spring boot·后端·elasticsearch
dl7431 小时前
一文看懂spring事件监听器
后端
Bunny02121 小时前
RBAC权限管理模型中的部门角色绑定方案优化
后端
小镇cxy2 小时前
开发者的新“超能力”——Claude Code 全面解析与使用指南
后端·claude