我使用 git 有一段时间了,但老实说,我很少关注凌乱的提交历史。最近在学习 git rebase ,想分享一下如何使用这个命令来压缩整理提交(Commits)
五步完成
简而言之,总共有五个步骤。
- 运行
git rebase -i head~x→x是需要从头开始压缩的数目,-i表示交互模式 - 按
i进入vim的INSERT的输入模式 - 将
pick更改为fixup或f - 按
ESC退出INSERT模式,然后输入:wq或者:x保存并退出 - 运行
git push -f更新新的commit(提交)
举例说明
我将举一个例子来详细说明一下~
Sisi是个程序员,他某天首先创建了一个git repo并使用 Readme.md 对其进行了初始化。他在这个文件里随意写了一句话。他运行 git add , git commit -m "add a readme file" , 和 git push 将此文件推送到 GitHub。提交历史如下
ff3acf2 (HEAD -> main, origin/main, origin/HEAD) add a readme file
245b1de Initial commit
很快,他发现这个文件有问题。因此他更改了该Readme文件并再次执行了三个 git 命令。然后提交历史变成如下
6646cc6 (HEAD -> main, origin/main, origin/HEAD) make some changes in readme
ff3acf2 add a readme file
245b1de Initial commit
出于可读性或任何其他原因,Sisi认为这两个最近的提交(commit)可以合并为一个Commit。他遵循了前面的五个步骤压缩来这两个提交,具体来说,
- 运行
git rebase -i head~2:注意,你不能在这里输入head~3因为目前只有两个提交 - 按
i进入vim的 INSERT 模式 - 将第二个
pick更改为fixup或简写为f,如以下代码块所示
pick ff3acf2 add a test file
f 6646cc6 make some changes in readme
# Rebase 245b1de..6646cc6 onto 245b1de (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
# commit's log message, unless -C is used, in which case
# keep only this commit's message; -c is same as -C but
# opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
-- INSERT --
注意在此,您不能将第一个pick更改为f,否则会出现如下错误
- 点击
ESC然后:wqor:x保存并退出 - 运行
git push -f更新新的提交
然后就大功告成了,commit历史变得非常清晰,如下
ff3acf2 (HEAD -> main, origin/main, origin/HEAD) add a readme file
245b1de Initial commit
现在最新的提交 6646cc6 实际上被压缩到提交了 ff3acf2,并且文件是也是最新的(第二次commit修改过的)
需要特别注意的
有一件小事需要你注意。到第 5 步时,如果你利用git status 检查 ,你会得到如下消息
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 2 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
此时,你应该运行 git push -f 而不是 git pull 。因为现在你的本地分支和原始远程分支之间已经有分歧了,运行git push -f 将推送一个压缩过的提交覆盖远程分支和本地分支(–force 标志允许您“强制推送”您对远程库所做的更改)。否则,如果在这里运行 git pull,两个提交将被拉到本地并导致合并,如下图所示
* fa8709c (HEAD -> main) Merge branch 'main' of https://github.com/lafengxiaoyu/Git-rebase-test
|\
| * 6646cc6 (origin/main, origin/HEAD) make some changes in readme
| * ff3acf2 add a test file
* | 35caab5 add a test file
|/
* 245b1de Initial commit
我很确定这不是你想要的,没错吧?










