一、rebase用在分支合并
1. 普通情况:
你在main分支上,开出一个feature分支,在feature分支上工作
某同事在main分支上push了新内容A2
如果想在feature分支获取到A2改动,则将main分支merge到feature分支,产生B1。这样git就记录了这个merge的信息。
有时候我们并不想要git记录这个merge的信息,因为这样会让git的历史记录变得很繁琐。而且会产生分叉。
回到merge前,如果将feature分支rebase到main分支,则是这样,是一条直线,没有分叉,相当清爽。rebase以后,老的提交B会被丢弃,会指向新创建的提交B‘。
2. 有相同commit的情况:
比如feature分支的第1个commit B 的改动和main分支的A2是一样的。
那么在执行git rebase main
以后,B就直接被删除掉了。
3. 在多条分支上操作的情况:
现在想将feature1分支上的改动放到main最新改动的后面,则执行git rebase --onto main feature feature1
,将变成:
实际项目中遇到的情况:在develop上修了个bug,需要把bug的分支接到release分支上:
执行git rebase --onto release develop bug
:
(当然也可以切换到bug
分支以后,直接执行git rebase release
)
二、在rebase的过程中,git做的事情:
- 把feature分支里面的每个commit取消掉。
- 把上面的操作临时保存成patch文件,存在.git/rebase目录下。
- 把feature分支更新到最新的main分支。
- 把上面保存的patch文件应用到feature分支上。
三、关于rebase过程中的冲突:
- 在rebase的过程中有可能产生冲突,这时候git会停止rebase并让你去解决冲突。
- 在解决完冲突后,用
git add <filename>
命令去更新这些内容。 - 然后执行
git rebase --continue
。 - 这样git会继续应用余下的patch补丁文件。
- 在期间可以使用
git rebase —abort
来停止rebase操作。回到rebase以前的状态。
四、为什么说git rebase是一个危险的命令?因为它改变了历史。
如果在rebase以前,feature分支不仅仅是你一个人在维护,还有其他同事在维护,那么在你将feature进行rebase并push到远程仓库以后,其他同事拉取代码就会产生问题。所以当所有需要rebase的commit没有被push过,就可以安全地进行rebase。
五、rebase用在其他方面(合并commit、删除commit、修改commit message等方面),下面用删除commit作例子:
- 切换到将要操作的分支
- 执行
git rebase -i HEAD~2
,进入vi窗口,查看近2个commit - 按键盘
a
键进入编辑模式 - 根据图中提示进行操作,比如我想
drop
掉70787b8
这个commit,将pick
改成d
。 - 按esc退出vi窗口。输入:
:wq
保存并退出。 - 命令行看到
Successfully rebased and updated refs/heads/feature.
说明70787b8
这个commit被删除掉了。
六、关于rebase成功以后的操作
- 执行完rebase以后,往往需要进行强制推送:
git push -f 分支名
(实际上git push -f
就行啦) - 如果想恢复到rebase之前的记录,可以执行
git reflog
以后,按箭头下,往下找到你想要回到的commit,复制。 - 再执行
git reset commit_hash_id --hard
,就能回到某个版本啦。
七、参考文档:
cloud.tencent.com/developer/n…