Git Rebase交互式合并详解

  1. 1. reword功能
  2. 2. edit功能
  3. 3. squash功能
  4. 4. fixup功能
  5. 5. exec功能
  6. 总结

本文简单介绍一下git rebase变基操作的交互式分支合并的过程,对于rebase不了解的同学可以参考官方文档。如下图,现在bob和alice分支都指向1901182 commit提交,master指向1c7af75 commit提交。

当前Git的分支示意图如下:

在bob分支上,先通过git rebase -i master通过交互式的方式在master分支的操作上进行变基操作。

如上图,git rebase 变基(合并)操作提供交互式的合并操作,在执行rebase -i命令后,弹出了上述文本框。可以让提交者选择以不同的方式将分支的提交合并到其他分支

编辑区前两行以pick开头的为在bob分支上的两次commit的hash值和commit log。rebase的合并的过程就是将这些commit对象合并到master分支上,此时如果删除一行,就会在rebase的过程忽略此个删除的commit

编辑区以”#”开头的都是rebase交互命令的一些说明,如下,具体含义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 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
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
  • p, pick = 合并这次提交
  • r, reword = 合并这次提交, 但是需要修改此次提交的日志信息
  • e, edit = 合并这次提交, 但需要对这次提交进行内容和日志的修改
  • s, squash =合并这次提交,但把这次提交和上一次提交融合在一起提交,会让提交者重新编辑提交日志。squash这个词用的好,把多个提交压扁在一起。
  • f, fixup = 和squash基本一样,差别在于直接丢弃此次提交的日志,使用上一次提交的日志,所以没有交互过程。
  • x, exec = 不合并这次提交,而是执行后面的shell命令。

rebase对于要合并的commit是从第一行开始进行重放,所以要知道操作顺序

1. reword功能

reword功能就是合并这次提交, 但是需要修改此次提交的日志信息。如下将1901182的commit进行reword操作,**将pick改成reword关键字(或r缩写)**。

保存后,就弹出了如下编辑提交日志的文本编辑框,将之前的提交日志”2”改为”rebase reword test”,保存退出后就会自动完成剩下的合并操作。

合并后,可以看到log如下:

合并后,分支的分叉图示如下:

2. edit功能

在上面reword修改的基础上,继续在bob分支上进行edit功能的测试,如下:

将b91312e提交改成edit操作,保存退出后,会有如下提示:

1
2
3
4
5
6
7
8
9
"git-rebase-todo" 20L, 652C written                                                   
Stopped at b91312e... rebase "reword" test
You can amend the commit now, with

git commit --amend

Once you are satisfied with your changes, run

git rebase --continue

可以看到,git rebase合并过程停在了b91312e提交上,当我们想要对这一次的提交进行修改时,我们可以使用git commit –amend命令。git commit –amend既可以对这次次提交的内容进行修改,也可以修改提交说明。

对这次提交的内容进行修改,并通过–amend命令进行提交,此时会提示是否需要对commit日志进行修改,保存后上个提交就被这次提交覆盖了。

git rebase –continue完成整个rebase合并过程

合并后,分支的分叉图示如下:

3. squash功能

在上面edit修改的基础上,继续在bob分支上进行squash功能的测试,前面已经解释了squash的功能:把这次提交和上一次提交融合在一起提交,会让提交者重新编辑提交日志。如下:将d82fbd3的提交和前一次06adc0d的提交合并成一次提交

将d82fbd3提交改成squash操作,保存退出后,会有如下提示:表示将要进行squash操作的两个提交的相关信息。

对上面的两次提交信息进行修改,如下,保存提交:

提交后的日志如下:可以看到d82fbd3和06adc0d两个提交被压缩成了一个92b4a88提交

合并后,分支的分叉图示如下:

4. fixup功能

我们把bob分支回滚到最开始的状态即alice的分支状态,继续测试rebase的fixup功能,fixup和squash功能基本一样,差别在于直接丢弃此次提交的日志,使用上一次提交的日志,所以没有交互过程。所以fixup相对使用频率比squash要高:

如下进行fixup合并后的日志:

5. exec功能

我们把bob分支回滚到最开始的状态,继续测试rebase的exec选项,exec的功能是:不合并这次提交,而是执行后面的shell命令。

如下:rebase过程放弃了1901182的提交,而是执行了上面的echo命令,不知道这个功能在什么情况下会使用到。

总结

在执行rebase/merge过程前最好的习惯是对本地开发分支进行备份:git branch develop_bak,防止合并过程出现什么问题,能够很轻松的回到合并前的状态