一次 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 的底层行为,才能在团队里安全高效地用好它们。

相关推荐
idaibin28 分钟前
"Git 多仓库用户身份自动切换与隐私保护指南
git·github
njsgcs1 小时前
sse mcp flask 开放mcp服务到内网
后端·python·flask·sse·mcp
小何好运暴富开心幸福1 小时前
C++之日期类的实现
开发语言·c++·git·bash
间彧1 小时前
Java单例模式:饿汉式与懒汉式实现详解
后端
道可到1 小时前
百度面试真题 Java 面试通关笔记 04 |JMM 与 Happens-Before并发正确性的基石(面试可复述版)
java·后端·面试
Ray662 小时前
guide-rpc-framework笔记
后端
37手游后端团队2 小时前
Claude Code Review:让AI审核更懂你的代码
人工智能·后端·ai编程
长安不见2 小时前
解锁网络性能优化利器HTTP/2C
后端
LSTM972 小时前
使用Python对PDF进行拆分与合并
后端
用户298698530142 小时前
C#:将 HTML 转换为图像(Spire.Doc for .NET 为例)
后端·.net