git rebase-优雅合并与修改提交
文章目录
- 简介
- rebase用于合并
- 使用rebase修改提交
- cherry-pick
简介
在Git核心概念图例与最常用内容操作(reset、diff、restore、stash、reflog、cherry-pick)中我们已经介绍了git的最常用实用的命令。
在上面说的那篇文章中,我们只是简单提了一下rebase。
是因为rebase比较复杂,并且用的相对较少,因为我们通常更喜欢用merge。
但是rebase绝对是有强迫症朋友的福音,尽管rebase非常危险,但是它非常优雅。
能让我们的提交历史看起来简洁清晰。
这一篇我们就来简单感受一下rebase命令的魅力吧。
rebase用于合并
rebase和merge一样,可以用来合并分支。
和merge不同,rebase不会创建一个新的合并节点。
而是把要合并的分支节点依次放在目标合并分支节点的后面。
我们看一下下面这个例子,先看一下基础提交:
我们先使用merge方式合并代码看看:
git merge feature-a
我们把merge回退了:
git reset --hard head^
用rebase来合并:
# 将feature-a rebase到当前分支
git rebase feature-a
# 等价于下面这个命令
git rebase feature-a master
有冲突,解决冲突之后,使用下面命令继续:
# 解决冲突之后add,表示冲突已经解决了,可以继续合并了
git add .
# 然后继续rebase
git rebase --continue
# 当然,我们也可以使用abort参数终止rebase
git rebase --abort
rebase合并完成之后的状态:
对于只有我们自己提交的功能分支,我们就可以使用rebase来合并。
merge合并的步骤:
- 将master分支的最新节点MN的快照
- feature分支最新节点CN的快照
- 与两个分支共同Parent节点MFN的快照执行三路合并生成新的快照
- 基于上一步合并之后的快照生成一个连接master分支与feature分支的节点MFN
- 将master指向最新合并节点MFN
rebase合并步骤:
- 找出当前所在分支和变基分支的共同Parent节点,MP
- 将feature分支中MP之后节点的快照暂存,如F1、F2、F3…
- 将上一步暂存的快照(F1、F2、F3…)应用到master分支,根据时间顺序
使用rebase修改提交
rebase除了用来合并分支,还可以用来修改提交。
命令 | 说明 |
---|---|
pick | 保留该commit,缩写:p |
reword | 保留该commit,需要修改该commit的注释,缩写:r |
edit | 保留该commit, 要修改该提交,和reword不同,edit不仅仅可以修改注释,缩写:e |
squash | 将该commit和前一个commit合并,缩写:s |
fixup | 将该commit和前一个commit合并,但不要保留该提交的注释信息,缩写:f |
exec | 执行shell命令,缩写:x |
drop | 丢弃该commit,缩写:d |
我们知道commit --amend可以修改提交,但是,只能修改最后一次,如果要修改多次,怎么办呢?
可以使用rebase。
git commit --amend -m 'commit message'
使用交互模式,修改最近5次提交:
git rebase -i HEAD~5
默认是pick表示使用提交,可以对这些commit上下移动从而对提交进行重排序,当退出编辑器时,git会按照指定的顺序去应用提交,并且做出相应的操作。
选择要修改的commit,选择对应的操作
根据提示继续操作:
我们根据提示,使用git commit --amend命令继续:
因为edit不仅仅可以修改提示,还可以修改其他,所以需要我们手动提示继续:
git rebase --continue
完成:
我们再看看修改之后的历史信息:
cherry-pick
之前文章我们已经介绍过cherry-pick,前面我们了解了rebase,再回过头来看cherry-pick。
可以发现cherry-pick,就是特殊的rebase。
# 首先切到指定分支
git checkout b1
# 查看需要pick哪些提交
git log --oneline
# 切回到pick分支
git checkout master
# cherry-pick指定的commit
git cherry-pick 1f54b01 0fed6dd
# 如果有冲突手动解决冲突,然后add
git add .
# 继续cherry-pick处理commit信息
git cherry-pick --continue