源起:
git rebase 用的还比较多,而且还常出现于面试之中,我会用,但是对其实在的意义没有深刻的理解,所以使用也非常的机械,局限,还常常混淆。
当我理解了rebase命令后,它的功能简言之就是“移花接木”,形象的比如,当一棵树的某条树枝非常的漂亮,唯独中间有个疤,办法就是将疤的地方给锯掉,然后将后面的枝给嫁接到新的根基上。所谓“变基”——rebase.
git rebase –onto newbase upstream branch
如何使用,我们先会提出几个问题:
- 1.”新枝”接到哪里?
- 2.”新枝”具体指的是那一段?
- 3.产生的变基新分支是在哪个分支上操作的?
Answer:
- 1.很明显是接到onto上。
- 2.是分支branch和upstream所diff的commit. upstream是上流,可以理解为是branch的上游分支,也就是起源分支之一。
- 3.branch分支
现实问题
问题1:
假设你有如下的branch tree:
o---o---o---o---o master
\
o---o---o---o---o next
\
o---o---o topic
你想要得到如下的branch tree:
o---o---o---o---o master
| \
| o'--o'--o' topic
\
o---o---o---o---o next
解决
git --rebase --onto master next topic
这个操作会把从next开始的commit嫁接到master上。如果你提供,那么首先会checkout到这个,然后再进行rebase操作。
问题2
我们想要删除F—G这两个commit
E---F---G---H---I---J topicA
解决
git --rebase --onto topicA~5 topicA~3 topicA
git rebase upstream branch
比如我们有如下的提交历史,当前的分支是topic
A---B---C topic(HEAD)
/
D---E---F---G master
想变成这样:
A'--B'--C' topic(HEAD)
/
D---E---F---G master
方法一
git rebase master
git rebase master topic
方法二:
git rebase master topic
git rebase master
第一种形式会首先checkout到topic分支,然后再执行rebase的操作。
那么rebase都做了什么事情呢?
首先,git会对branch分支和upstream做一个差集,把不同的commit找出来,类似于执行git log upstream..HEAD,对于以上例子来说结果就是A—B—C,然后把这些commit存在一个临时的地方。
其次,git会把当前分支branch reset到upstream上,类似于执行git reset –hard upstream命令。对于以上例子来说就是reset到master。
最后,git把第一步中暂存的commit,按照顺序一个一个地应用到分支上,相当于一个一个重复提交,这就是为什么rebase之后commit的hash值变了。
如果中的一个commit进行了某项修改,而当前分支中也存在一个commit,这两个commit的修改的内容一样,那么当前分支中的commit将会被忽略。比如以下的A和A’就是这样两个commit。
A---B---C topic
/
D---E---A'---F master
执行完git rebase master之后,结果如下:
B'---C' topic
/
D---E---A'---F master
换种思路来:
git rebase --onto master master topic
git rebase –continue
同样,rebase也会产生冲突,当解决完冲突之后你可以继续rebase的进程:
git rebase --continue
git rebase –abort
或者取消此次rebase:
git rebase --abort
git rebase -i
关于commit修改、顺序调整、合并等操作可以通过rebase -i来完成
git rebase -i <upstream>
此命令最常被用到
-i
–interactive
-i 意思是指 交互式,在执行该命令后,会呈现一张可rebase的commits的列表,在rebase前交给用户自由编辑。
每一行commit 删掉了,那么整个这次提交相应会被删除。而且还能依次修改提交的顺序。
参考链接:
Git-rebase 小筆記 –> todo 通过这个继续深入学习一下吧!