我使用 git 有一段时间了,但老实说,我很少关注凌乱的提交历史。最近在学习 git rebase ,想分享一下如何使用这个命令来压缩整理提交(Commits)

五步完成

简而言之,总共有五个步骤。

  1. 运行git rebase -i head~xx 是需要从头开始压缩的数目,-i 表示交互模式
  2. i 进入vimINSERT的输入模式
  3. pick更改为 fixupf
  4. ESC 退出 INSERT 模式,然后输入 :wq或者 :x保存并退出
  5. 运行 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。他遵循了前面的五个步骤压缩来这两个提交,具体来说,

  1. 运行git rebase -i head~2 :注意,你不能在这里输入 head~3 因为目前只有两个提交
  2. i 进入 vim 的 INSERT 模式
  3. 将第二个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,否则会出现如下错误

错误:没有先前的提交就无法“修复”

  1. 点击 ESC 然后 :wqor :x 保存并退出
  2. 运行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

我很确定这不是你想要的,没错吧?

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐