git rebase核心作用把你当前分支上的提交重新“搬到”另一个分支的最新提交后面。通俗说就是你本地写了几个 commit但主分支master/main/dev已经被别人更新了。你想让自己的代码基于最新主分支继续开发就可以用rebase。1. 先看普通开发场景假设公司远程分支是origin/dev: A --- B --- C你从B拉出来开发了两个提交你的 feature 分支: A --- B --- D --- E但是别人已经把C合进了devorigin/dev: A --- B --- C现在整体是这样D --- E 你的 feature / A --- B --- C origin/dev你执行gitcheckout featuregitfetch origingitrebase origin/devrebase 之后变成A --- B --- C --- D --- E注意D、E会变成D、E因为它们被“重新应用”了一遍commit id 会变。2.rebase和merge的区别用mergegitcheckout featuregitmerge origin/dev结果可能是D --- E -------- M / / A --- B --- C ----------会多一个合并提交M。用rebasegitcheckout featuregitrebase origin/dev结果是A --- B --- C --- D --- E历史更直看起来像你是基于最新dev开发的。所以很多公司喜欢gitpull--rebase而不是普通gitpull因为普通pull默认可能会产生 merge commit。3. 最常用命令场景一更新自己的开发分支你在feature_xxx分支开发想同步最新devgitcheckout feature_xxxgitfetch origingitrebase origin/dev这就是最常见用法。场景二拉代码时直接 rebase普通拉取gitpull可能会自动 merge。推荐写法gitpull--rebase等价于gitfetchgitrebase origin/当前分支例如你在dev分支gitpull--rebaseorigin dev4. rebase 遇到冲突怎么办执行gitrebase origin/dev如果冲突了Git 会提示类似CONFLICT (content): Merge conflict in main.c这时候流程是第一步看冲突文件gitstatus你会看到哪些文件冲突了。第二步打开冲突文件里面可能是这样HEADintspeed100;intspeed200;D含义 HEAD 这是目标分支 origin/dev 上的内容 这是你自己提交里的内容 你的提交你手动改成最终想要的比如intspeed200;然后删除、、这些标记。第三步标记冲突已解决gitaddmain.c第四步继续 rebasegitrebase--continue如果还有冲突继续重复改文件gitadd文件gitrebase--continue5. 想放弃 rebase 怎么办如果 rebase 到一半你懵了不想继续了gitrebase--abort它会回到 rebase 之前的状态。这个命令很重要记住gitrebase--abort6. interactive rebase整理 commit 用的这个也很常用尤其是 Gerrit / Code Review 前。比如你最近提交了 3 个 commitgitlog--oneline看到a3c1111 fix typo b2d2222 add uart driver c1e3333 debug print你想整理最近 3 个提交gitrebase-iHEAD~3会打开一个编辑界面pick c1e3333 debug print pick b2d2222 add uart driver pick a3c1111 fix typo常用操作pick 保留这个 commit reword 修改 commit message squash 合并到上一个 commit并合并 message fixup 合并到上一个 commit但丢掉当前 message drop 删除这个 commit比如你想把fix typo合并到add uart driverpick c1e3333 debug print pick b2d2222 add uart driver fixup a3c1111 fix typo保存退出后Git 会帮你整理提交。7. 嵌入式项目里最常用的 rebase 流程假设你在公司开发cat_litter_motor_ctrl分支主分支是dev# 1. 切到自己的开发分支gitcheckout cat_litter_motor_ctrl# 2. 拉取远程最新代码gitfetch origin# 3. 把自己的提交搬到最新 dev 后面gitrebase origin/dev# 4. 如果有冲突解决冲突gitstatus# 手动改冲突文件gitaddxxx.cgitrebase--continue# 5. rebase 完后看提交历史gitlog--oneline--graph--decorate--all如果你之前已经推送过这个分支rebase 后 commit id 变了普通 push 会失败需要gitpush --force-with-lease不要随便用gitpush-f更推荐gitpush --force-with-lease它比-f安全一些防止你把别人新推的代码覆盖掉。8. 最重要的禁忌不要随便 rebase 公共分支。比如这些分支不要乱 rebasemaster main dev release尤其是多人都在用的远程分支。适合 rebase 的是你自己的开发分支feature_xxx bugfix_xxx my_uart_debug一句话自己的分支可以 rebase 大家共用的分支不要乱 rebase。9. 你实际最常用记这几个就够了# 更新远程信息gitfetch origin# 把当前分支变基到最新 devgitrebase origin/dev# 解决冲突后继续gitadd.gitrebase--continue# 放弃 rebasegitrebase--abort# 拉代码时使用 rebasegitpull--rebase# 整理最近 3 个提交gitrebase-iHEAD~310. 跟 Gerrit 的关系你之前用过 Gerrit / repo这里 rebase 很常见。比如你提交 review 前远程tws-dev更新了你本地 patch 落后了通常流程是gitfetch origingitrebase origin/tws-devgitpush origin HEAD:refs/for/tws-dev如果 Gerrit 提示冲突基本就是让你先在本地 rebase 到最新目标分支再重新推 review。可以把rebase理解成一句话我写的代码不变但我想假装自己是在最新代码基础上写的。所以它会把你的 commit 一个一个摘下来然后重新放到最新分支后面。