Using Git Rebase to Manage Commit History

Using Git Rebase to Manage Commit History

使用场景

在开发过程中,可能会有这样的情况:你在开发一个功能时,提交了多次 commit,但是这些 commit 并不是一个完整的功能,或者是一个 bug 修复,这时候你可能会想要将这些 commit 合并成一个 commit,以便于更好的管理提交历史。这时候,git rebase 就派上用场了。通过这个命令,对 git 提交历史进行整理,可以使提交历史更加清晰。需要注意的是,如果你已经将这些 commit 推送到了远程仓库,那么你需要使用git push --force来推送你的更改。

Warning

⚠️️ 在多人协作的项目中使用 git rebase 需要注意尽量不要对已经推送到远程仓库的 commit 进行 rebase 操作,因为这样会改变提交历史,可能会导致其他人在合并你的提交时出现问题。推荐的使用场景是在本地开发过程中使用 rebase 整理提交历史。

Commands:

  • p, pick = use commit
  • r, reword = use commit, but edit the commit message
  • e, edit = use commit, but stop for amending
  • s, squash = use commit, but meld into previous commit
  • f, fixup = like "squash", but discard this commit's log message
  • x, exec = run command (the rest of the line) using shell
  • d, drop = remove commit

合并多个 commit

如何确定你想要合并的 commits 的范围呢?

例如,如果你想要合并最近的三个 commit,你可以使用 HEAD~3。这将打开一个编辑器(core.editor),列出最近的三个 commit。
你也可以使用git rebase -i <commit>指定 commit 的 hash 值。例如git rebase -i 8c0a3c,这将打开一个编辑器,列出从 到 HEAD 的所有 commit。
运行git rebase -i HEAD~3

注意:git rebase 只能合并连续的 commit,如果你想要合并不连续的 commit,你需要多次运行 rebase 命令
你可以通过设置环境变量来指定使用的编辑器,例如:git config --global core.editor "nvim" 将使用 nvim 编辑器。
这里推荐lazyvim以及 lunarvim,这两个 vim 配置都是基于 neovim 的,功能强大,配置简单,推荐使用。且对于在终端中运行支持良好。

在编辑器中,将第二行和第三行的 pick 改为 squash 或 s;然后保存修改并退出,这将打开另一个编辑器,让你编辑新的 commit 信息。更多命令见下表 Commands 内容

vim 使用命令2,3s/pick/s可替换 2-3 行的picksquash,2,3 指定行;s/pick/s/表示 Substitute a with b;


编辑 commit 信息,然后保存并关闭编辑器。如果一切顺利,你的三个 commit 现在应该已经被合并成一个了。

这将改变你的 Git 历史。如果你已经将这些 commit 推送到了远程仓库,你将需要使用git push --force 来推送你的更改

修改 commit

如下是一个 git 提交历史,to fix提交中有处错误,1 == 2,要修改该提交中的错误可以使用git rebase -i HEAD~2

1
2
3
4
* 7f3af51 (HEAD -> main) 4th
* a14992f to fix
* b16a285 second_amend
* c6bb6ae first
commit: to fix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ git rebase -i HEAD~2

[.git/COMMIT_EDITMSG]
- pick a14992f to fix
+ edit a14992f to fix
pick 7f3af51 4th
保存退出

$ vim ./fix.md
- 1 == 2
+ 1 !=2
保存退出
$ git add ./fix.md
$ git commit --amend

[.git/COMMIT_EDITMSG]
- to fix
+ fixed
保存退出

$ git rebase --continue

此时的 commit 历史如下:

1
2
3
4
* dc6de4f (HEAD -> main) 4th
* a33b9a0 fixed
* b16a285 second_amend
* c6bb6ae first
commit: fixed

Ref

git scm——git-rebase
git-rebase——atlassian

Using Git Rebase to Manage Commit History

https://efterklang.github.io/Dev/Git/rebase-and-quash/

Author

Efterklang

Posted on

2024-04-27

Updated on

2024-09-18

Licensed under

Comments