基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

如何将本地的多个连续 commit 合并(Squash)成一个 commit?

知识点图片

在 Git 中,将本地多个连续的 commit 合并(Squash)成一个 commit,最常用的方法有两种:交互式变基(Interactive Rebase)软重置(Soft Reset)

下面为你详细介绍这两种方法。


方法一:使用交互式变基 git rebase -i(最经典、最推荐)

这种方法允许你精确控制要合并哪些 commit,并且可以保留或修改之前的 commit message。

步骤:

1. 确定要合并的 commit 数量
假设你想把最近的 3 个 commit 合并成一个,运行以下命令:

bash
git rebase -i HEAD~3

(注意:如果你想合并的 commit 不是最近的,你需要找到你要合并的最早的 commit 的*前一个 commit 的 hash 值,例如 git rebase -i <commit-hash>)*

2. 在编辑器中修改指令
运行命令后,Git 会自动打开一个文本编辑器(通常是 Vim 或 Nano)。你会看到类似这样的内容,注意顺序是从旧到新排列的

plaintext
pick 1a2b3c4 第一个 commit 的信息
pick 5d6e7f8 第二个 commit 的信息
pick 9g0h1i2 第三个 commit 的信息

# Rebase ...
# Commands:
# p, pick <commit> = use commit
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message

你需要保留第一行的 pick,把下面几行的 pick 改成 squash(或简写为 s)。
修改后如下:

plaintext
pick 1a2b3c4 第一个 commit 的信息
s 5d6e7f8 第二个 commit 的信息
s 9g0h1i2 第三个 commit 的信息

提示:如果你想直接丢弃后面两个的 commit message,可以用 f (fixup) 代替 s

修改完后,保存并关闭编辑器(Vim 的操作是按 Esc,输入 :wq,然后回车)。

3. 编辑合并后的 Commit Message
上一步保存后,Git 会立刻弹出另一个编辑器界面,展示这几个 commit 原本的留言,让你编写新的合并后的 commit message。

plaintext
# This is a combination of 3 commits.
# The first commit's message is:
第一个 commit 的信息

# The 2nd commit's message is:
第二个 commit 的信息

# The 3rd commit's message is:
第三个 commit 的信息

你可以把这些内容全部删掉,写上你最终想要的、简洁明了的一句话。保存并退出编辑器。

完成!你已经成功把 3 个 commit 合并成 1 个了。可以使用 git log 查看结果。


方法二:使用软重置 git reset --soft(最简单、快捷)

如果你不在乎保留之前的 commit message,只想快速把最近的几次修改揉成一个提交,这个方法非常快。

步骤:

1. 撤销最近的 n 个 commit,但保留代码更改
假设你要把最近的 3 个 commit 合并,运行:

bash
git reset --soft HEAD~3

这个命令会把当前分支的 HEAD 指针往回退 3 步,但你修改过的代码依然保留在暂存区(Staging Area)

2. 重新提交
此时,你只需要直接执行一次新的 commit 即可:

bash
git commit -m "这是合并后的新 commit 留言"

⚠️ 重要注意事项(如果你的代码已经 Push 到了远程)

如果你要合并的这些 commit 之前已经 git push 到远程仓库了,因为你修改了本地的 Git 历史,直接 git push 会报错。

这时候你需要强制推送:

bash
git push -f origin <你的分支名>

(或使用更安全的 git push --force-with-lease)

🚨 警告:
绝对不要在公共分支(如 main, master, develop)上强制推送修改历史的代码!这会严重影响其他同事的开发。合并 commit 操作通常只在自己的特性分支(feature branch)上进行。

00:00
00:00