git rebase使用方法和后续可能使用的技能

32 阅读10分钟

git rebase

git rebase 是 Git 中非常强大但也需要谨慎使用的命令,主要用于“整理提交历史”,它的核心作用是:把一个分支的提交“挪到”另一个分支上去,并重放这些提交,从而让提交历史更清晰、线性。

一、什么时候使用 git rebase

1. 保持提交历史整洁

当你的 feature 分支落后于主分支(如 maindevelop)时,可以使用 rebase 将最新的主分支变更“融合”进来,而不是用 merge

bash
复制编辑
git checkout feature
git rebase main

相比于 merge,这不会产生额外的 merge commit,提交历史更干净、线性,便于 review 和回溯。


2. 整理提交(交互式 rebase)

在本地开发过程中,可能提交了一堆小的 commit,例如修 bug、调试等,可以通过交互式 rebase 合并它们。

bash
复制编辑
git rebase -i HEAD~5

你可以选择:

  • squash(合并)
  • reword(修改 commit message)
  • drop(删除提交)

使用场景: 在提交代码前进行“美化”,比如准备 push 到远程或提 PR 前。


3. 修改历史提交信息

例如你想修改上一次提交的 message:

bash
复制编辑
git commit --amend
# 或者
git rebase -i HEAD~2

4. 拉取远程分支时保持线性历史

默认情况下 git pullfetch + merge,可以使用:

bash
复制编辑
git pull --rebase

这样在拉取别人推送的提交时,会自动把你本地的 commit “重放”在最新的远程提交后,避免产生 merge commit。

二、常见使用场景总结

使用场景是否适合使用 rebase说明
本地开发整理提交历史✅ 是使用 git rebase -i 美化 commit
Feature 分支同步主干代码✅ 是git rebase main 保持提交线性
修复远程 push 错误提交❌ 慎用若已推送,rebase 后需强推,可能影响他人
多人协作的公共分支❌ 慎用rebase 会更改历史,其他人会冲突或丢失历史
自动化 CI/CD 项目✅ 可用在构建前保持提交整洁,提升可读性

三、注意事项

  • 不要对已推送的公共分支执行 rebase!
    因为 rebase 会重写历史,如果别人已经基于你原来的提交开发了,会导致冲突和混乱。
  • 本地分支尚未推送前,可以放心使用 rebase

git rebase --continue:解决冲突后继续 rebase

  • 作用: 当你解决了当前的冲突并 git add 所有冲突文件后,继续执行 rebase 剩下的提交。

  • 使用场景: 你已经解决了当前冲突,想让 rebase 接着进行:

bash
# 解决冲突
git add .

# 继续 rebase
git rebase --continue

git rebase --skip:跳过当前这个有问题的提交

  • 作用: 不处理当前冲突的提交,直接跳过它(即忽略当前这次提交)。

  • 使用场景: 如果你觉得当前这个提交无关紧要、不重要,可以直接跳过它:

git rebase --skip
  • 注意: 这个提交就会从 rebase 后的新历史中消失。

git rebase --abort:放弃 rebase,恢复到操作前的状态

  • 作用: 取消当前的 rebase 操作,把代码恢复到 rebase 之前的状态。

  • 使用场景: 如果你发现冲突太复杂、搞错了分支、rebase 不适合当前情况,可以“后悔”:

git rebase --abort

三者对比总结:

命令场景行为说明
git rebase --continue你解决了冲突继续 rebase常用
git rebase --skip不想保留当前冲突的提交跳过当前提交会丢弃该次提交
git rebase --abort想放弃 rebase还原到原始状态安全回退

冲突解决三种方案演示

1. 使用 --continue:解决冲突后继续 rebase

步骤:

# 1.手动编辑把冲突解决掉:

# 2.添加解决后的文件
git add file.txt

# 3.继续 rebase
git rebase --continue

2. 使用 --skip:跳过当前提交,不保留这个提交

git rebase --skip

结果: feature 分支当前这次提交被跳过,不再出现在 rebase 后的提交历史中。

3. 使用 --abort:放弃 rebase,回到 rebase 之前的状态

git rebase --abort

结果: Git 会将 feature 分支还原到 rebase 前的状态,什么也不会变动。

总结图示(冲突后你可以做什么)

[冲突发生]
      ↓
  解决冲突?
      ↓
[是] → git add → git rebase --continue → ✅ 继续
[否] → 想放弃?  → git rebase --abort    → 🔙 撤销
     → 想跳过?  → git rebase --skip     → 🚫 忽略该提交

rebase commit合并

例如,你最近提交了 3 次:

git log --oneline
e8f1d23 修改样式
a4b5c67 修复 Bug
9bd4e11 新增功能

你想把这三个合并成一个提交。

操作步骤如下:

第一步:使用交互式 rebase

git rebase -i HEAD~3

HEAD~3 表示你要修改最近的 3 个提交。

第二步:修改指令,把除了第一个保留为 pick,其余改为 squash(或 s)

编辑器打开后类似这样:

pick 9bd4e11 新增功能
pick a4b5c67 修复 Bug
pick e8f1d23 修改样式

你改成这样 👇:

pick 9bd4e11 新增功能
squash a4b5c67 修复 Bug
squash e8f1d23 修改样式

第三步:修改最终的提交信息(可选)

下一步 Git 会让你输入合并后的提交信息,你可以自定义,比如:

新增功能、修复 bug、调整样式

保存退出(一般是 :wq 或 Ctrl+S + Ctrl+W depending on your editor)。

第四步:完成后检查

git log --oneline

你会看到这三个提交合并成了一个新的 commit,提交 ID 也变了。

指令总结

指令含义用途
pick保留这个提交默认操作
reword修改提交信息,但保留代码改 message 不改内容
edit暂停在此提交,允许修改内容想修改该次提交的代码
squash合并当前提交到上一个,合并提交信息压缩多个 commit(保留 message)
fixup合并当前提交到上一个,丢弃提交信息快速合并,不留痕迹
drop删除该次提交不保留

技能总结

类别命令简要说明
基础git rebase main把当前分支放到 main 后
冲突处理--continue / --skip / --abort继续 / 跳过 / 取消
交互式-i HEAD~N编辑最近 N 次提交
修改行为pick reword edit squash fixup drop控制每一个提交
安全替代git pull --rebase拉取代码避免 merge commit

rebase常见编辑器操作方式(根据你默认的 Git 编辑器不同)

1. 如果打开的是 Vim(Git 默认编辑器)

Vim 是 Git 默认使用的终端编辑器。

  • 初始是“命令模式”,不能直接输入内容。

  • 你需要按:

i        ← 进入插入模式(insert mode)
  • 然后你就可以移动光标,把 pick 改成 squash 等。

  • 修改完成后:

Esc         ← 退出插入模式
:wq         ← 保存并退出(输入冒号后输入 wq,然后回车)

Vim 快速操作流程回顾:

操作键盘操作
进入插入模式i
退出插入模式Esc
保存并退出:wq + 回车
退出不保存:q! + 回车

rebase后 git push -f 使用场景

git push -f 是强制把你本地的分支覆盖远程分支,即使两者提交历史不一致。

1. rebase 或修改历史之后需要强推

举例:

你在本地对提交历史做了如下操作:

git rebase -i HEAD~3
# 或
git commit --amend

这些命令会修改 commit 的历史(提交 ID 会改变), 这时候如果你尝试推送:

git push

Git 会提示:

! [rejected]        main -> main (non-fast-forward)

此时你需要:

git push -f

来强制用你的本地历史覆盖远程分支。

更安全的替代: git push --force-with-lease

git push --force-with-lease

总结

使用场景是否用 -f原因
本地 rebase 后推送✅ 是本地提交 ID 改变了
修改历史删除敏感信息✅ 是覆盖远程历史
重置分支到早期状态✅ 是压缩/清理提交
正常协作开发❌ 否会影响他人
公共分支(如 main❌ 否高风险,避免使用

git commit --amend 是一个非常实用的 Git 命令,它用于修改最近的一次提交。

git commit --amend

运行后 Git 会打开你的编辑器(如 Vim 或 VS Code),让你修改提交信息。 内容不变,只有 message 被改。

1. 修改上一次提交的 commit message(但内容不变)

git commit --amend

运行后 Git 会打开你的编辑器(如 Vim 或 VS Code),让你修改提交信息。 内容不变,只有 message 被改。

2. 补充忘记添加的文件进上一次提交

你提交了代码,但忘记加某个文件,可以这样做:

# 添加漏掉的文件
git add forgotten-file.js

# 修改上一次提交,加入刚刚添加的文件
git commit --amend

这会把新加的内容合并进上一条提交,而不是生成一个新的提交。

3. 调整提交内容或格式(比如改文件名、修 typo)

可以在提交后马上发现错误,修复后:

# 修 typo 后重新 add
git add .

# 用 amend 覆盖上一次提交
git commit --amend

提交历史发生了什么?

执行 git commit --amend 后:

  • 原来的提交会被 删除

  • Git 创建一个新的提交(包含你改后的内容和信息)

  • 新提交 ID 会改变

所以如果你已经 git push 过了,就需要用:

git push -f

✅ 总结口诀

用途命令说明
改 messagegit commit --amend不用 add,只改文字
补充文件git add file && git commit --amend把文件合进上一提交
改了历史git push -f修改了提交 ID,需要强推

如果你 本地删除了一个分支,而且线上(远程)也没有备份记录,那就相当于这个分支被彻底删了 —— 除非你有“找得回”的线索,比如分支上的 commit 还没被 Git 的垃圾回收清理掉。

git操作中误删本地commit后:

1. 你是否还记得该分支的提交哈希(commit id)?

  • 如果你有记录下来的 commit id,可以直接恢复:
git checkout -b 恢复的分支名 提交ID

2. 你是否曾经切换到这个分支、做过提交?

即使你删除了分支,Git 也会暂时保留它的历史在 reflog 中(默认保留 90 天)。这时候你就有救!

恢复本地已删除的分支的步骤(用 git reflog):

第一步:查看最近 Git 操作记录

git reflog

你会看到类似这样的输出:

a1b2c3d HEAD@{0}: checkout: moving from feature-abc to main
e4f5g6h HEAD@{1}: commit: 完成了按钮功能
...

你可以从这里找到你曾经在该分支上提交的 commit id(比如 e4f5g6h)。

第二步:基于旧的 commit 恢复分支

git checkout -b 新分支名 e4f5g6h

✅ 恢复成功!

🧪 补充技巧(恢复“最近删除的分支”):

你也可以用这个命令找回被删除的分支最近的 commit:

git fsck --lost-found

它会列出所有“悬空”对象,你可以从中找到对应的提交,再手动 checkout 回来。

✅ 总结操作指令:

场景命令说明
查找历史提交git reflog找到被删分支的提交 ID
恢复分支git checkout -b 新分支 提交ID基于旧提交创建新分支
列出悬空对象git fsck --lost-found高级用法,找回“孤儿提交”