git高级用法之rebase

rebase的高级用法,这里介绍两种高级用法:
1、合并连续的或者不连续的两个提交记录、删除任意一个提交记录、改变提交记录的先后顺序
2、通过rebase合并分支。

合并连续的两个提交

如下图的场景:(gl是git log的缩写,不过也没这么简单,要设置类似下图中简洁的log,可以参考本人博客中的文章【git配置】)
在这里插入图片描述
第一次提交了某个功能的修改,后面又优化了一些,这样同一个功能有两个提交记录,有点辣眼睛。这时我们可以用rebase来合并两个提交:

git rebase -i 0f31175

提示:各位需要重点注意上述命令中最后的参数。这个值,需要是我们待操作的记录的前一次提交的hash值。这个在rebase所有操作中都是如此的规律。这个值是告诉git,后面的操作是基于哪个提交进行的。在接下来的介绍中,我们把这个基础版本定为base版本,用base代指这个提交节点。
输入rebase命令后,会弹出类似如下的提示:
在这里插入图片描述
我们要把【又修改函数func_1】合并到【修改函数func_1】一起,所以根据上述图片注释中的提示,我们把【又修改函数func_1】前面的pick改成squash,或者直接简写s也行。如下所示:
在这里插入图片描述
然后保存退出,会弹出类似如下提示:
在这里插入图片描述
这里是让我们编辑合并后的提交日志的,我们可以把第二行【又修改函数func_1】删掉,只保留上面的一行即可,然后保存退出。这时,如果没有冲突,git会提示success:
在这里插入图片描述
如果没有冲突,即成功之后,我们看下log:
在这里插入图片描述
会发现两个提交只剩一个了,他们是合并了,而不是删除了某一个。各位可以用git show 01e5706看下合并后的提交内容即可。

合并两个提交,是rebase应用中最简单的一个,也是最基础的一个,所以这里我稍微说的详细一些。上面多次提到没有冲突的情况下这几个字眼,就是说,我们这次演示是没有冲突的,在平时的使用中是可能会出现有冲突的情况的,这个时候rebase会失败。失败之后有两种解决方法,一种是直接abort,另一种方法是解决冲突之后继续rebase。
abort的方法是,当出现冲突后,在命令行输入

git rebase --abort

然后一切就回到没有rebase之前的状态了。
解决冲突的方法,和git通用的解决冲突类似,解决完冲突后,输入:

git rebase --continue

就可以接着走被打断的rebase流程。

合并两个不连续的提交

如下图的场景:
在这里插入图片描述
在提交了某些功能之后,又修改了之前某个功能。我想把这两次合并,来看rebase如何出色的完成。
这个我们得分两步进行:
1、将【又又又修改函数func_1】的提交记录移动到www和eee之前,即和【修改函数func_1】放在一起,而且要放在【修改函数func_1】的后面,即:要看起来是先提交了【修改函数func_1】,然后提交了【又又又修改函数func_1】;
2、使用上面介绍的方法,将两个提交合并为一个提交。
下面开始实施。
第一步:修改顺序。根据rebase的提示,我们是可以改变提交的顺序的。我们使用0f31175版本作为base,使用如下命令:

git rebase -i 0f31175

然后弹出:
在这里插入图片描述
我们编辑这个文本,将【又又又修改函数func_1】所在行移动到【修改函数func_1】下面。这个顺序十分重要,因为git会根据这里的顺序从上到下依次在base版本基础上依次提交列出来的记录。
修改后如下所示:
在这里插入图片描述
rebase原理小透漏:我们这样改了之后,git内部会先回退到base版本,然后按照我们修改后的顺序依次提交。所以rebase之后,在base之后每个提交的hash值都变了,而在包括base在内的之前的版本,hash值都不变。

我们保存提交:
在这里插入图片描述
可以看到,顺序已经如我们所愿的调整了。
第二步:根据上面介绍的,使用rebase合并提交的方法,将【又又又修改函数func_1 】合并到【修改函数func_1】中即可。

删除提交

到这里,就不用详细介绍了。如下所示,要把【扯淡的需求】这个提交删掉:
在这里插入图片描述
我们把2d68911作为base版本,输入:

git rebase -i 2d68911

在这里插入图片描述
如上图所示,将要删除的行前面的pick改为d,然后保存退出即可,然后看log:
在这里插入图片描述
可以看到,扯淡的需求已经被删掉了。

通过rebase合并分支

有同学可能会说,合并分支用git merge不挺好吗?但是你有没有发现,如果用merge,很可能每merge一次,都会多出来一个merge的记录。会导致提交记录很不美观。如下图所示是用merge合并分支的效果:
在这里插入图片描述
如果是用rebase合并分支,是不会有这些多余的提交记录的,只会完成真正意义上的合并。
这里提一句,为什么merge提交会导致多出来一个提交呢?merge有两种合并模式,一种是fast forward模式,一种是三路合并模式。当使用三路合并模式的时候,会多出来一个提交,而使用fast forward模式的时候,不会多出来额外的提交。以上图中的分支master和develop为例说明这两种模式。我们假设develop分支是从master分支某个base节点基础上创建的新分支,如果在base节点之后,master分支上没有任何提交,而只有develop分支在base节点上有一些提交,那么这时,通过merge将develop分支合并到master分支,merge会使用fast forward模式,且不会在master上产生多余提交。但是,如果在base节点之后,master和develop分支都各自有所提交,那么将develop分支合并到master分支上的时候,git就会采用三路合并的方式merge,并且合并完后,会生成一个多余的节点。

所以,如果在base节点之后,master分支上没有任何提交,我们完全可以使用merge合并分支,因为这时git会采用fast forward模式merge,不会产生一个多余的节点。但是当我们预判出git要采用三路合并的方式merge的时候,这时就可以采用rebase合并,来避免git产生多余的节点。

我们先来演示一下rebase合并:
在这里插入图片描述
上图展示了当前master分支和develop分支目前的情况。两个分支在【base_版本】基础上都各自有所提交,现在我想把develop分支上的提交合并到master分支上,需要以下两步:

git co develop     //切换到develop分支
git rebase master    //以master分支最新提交为base,将develop分支上独有的提交在base基础上依次提交一遍。

执行rebase后,git会打印重新提交的过程:
在这里插入图片描述
可以看到,git依次在base基础上提交了develop分支上独有的。
接下来看看develop分支的记录:
在这里插入图片描述
可以看到,develop分支原来独有的提交,现在都在master分支之后了。
但是注意:上述操作后,develop分支上新的提交依然在develop分支上,并没有合并到master分支上,要完成合并,还需要使用merge,不过此时merge是fast forward模式的,不会产生新的多余节点。
在这里插入图片描述
最终看下master分支上的log:
在这里插入图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值