本系列汇总,请查看这里:https://www.cnblogs.com/uncleyong/p/10854115.html
关于rebase
rebase用来变基,就是重新定义(re)起点(base)的作用,即重新定义分支的版本。
在执行变基的过程中,三个常用命令:
- git rebase --skip 它表示丢弃当前补丁的重放,即忽略掉当前补丁
-
- git rebase --abort 它表示终止正在进行的变基操作,并且恢复到最初始的状态
-
- git rebase --continue 它表示继续补丁的重放,一般在解决冲突后执行该命令
演示场景
在合并分支过程中,可能会遇到冲突,本篇演示用rebase解决本地冲突。
基于master主分支,创建两个开发分支dev_a和dev_b,分别做修改:
dev_a第一次修改并提交到本地仓库,然后推送到远程仓库
dev_b第一次修改并提交到本地仓库,然后推送到远程仓库
dev_a第二次修改并提交到本地仓库,然后推送到远程仓库
dev_b第二次修改并提交到本地仓库,然后推送到远程仓库
先合并dev_a:切换到dev_a,rebase master分支,没有冲突,然后切换到master,进行merge
然后合并dev_b:切换到dev_b,rebase master分支,产生冲突,解决冲突,然后切换到master,进行merge,最后push到远程master分支
准备数据
远程数据
远程commit id
克隆到本地
文件内容
创建dev_a分支
修改qzcsbj.txt内容,然后提交到本地仓库
切换到master,创建dev_b分支
修改qzcsbj.txt内容,然后提交到本地仓库
再次切换到dev_1做一次提交,然后推送到远程仓库
再次切换到dev_2做一次提交,然后推送到远程仓库
远程分支内容
合并分支并解决冲突
切换到master,拉取最新master
先合并dev_a,下面没有冲突,变基成功并更新refs/heads/master
切换到master进行merge
push到远程
然后合并dev_b分支,产生冲突,冲突文件是qzcsbj.txt
也可以这样查看冲突的文件:git diff --name-only --diff-filter=U
查看分支差异:git diff master dev_b
冲突文件内容:
HEAD(ef2d957)表示dev_b第一次提交
修改冲突文件
add
继续rebase
第一行改为:
保存退出后的结果:生成的新提交id是bd16a7c
依然有冲突,HEAD(bd16a7c)表示dev_b第二次提交
冲突文件内容:
修改冲突文件,然后add
继续rebase
第一行改为:
保存退出,结果:变基成功并更新refs/heads/master
文件内容:
切换到master,执行merge
master送到远程仓库
如果dev_b在合并前做了很多次commit,那么就要处理很多次冲突,每次解决后执行git rebase --continue
对于单条分支,rebase能够合并多个commit,将多个提交合并成一个提交,命令是:
git rebase -i [commit id]
合并commit id之前的所有commit;-i选项能够提供一个交互界面,分阶段修改commit信息并rebase。
查看分支合并图
git log --graph --oneline
git log --graph
结论:会修改提交历史,无法直观地看出哪些提交是在原分支上完成的,历史记录是一条直线(线性),会显得更为整洁,合并图更易读
分支后续操作
此时分支如果不要了就可以删除
如果要继续在分支在开发,需要同步master分支,rebase即可:
- 切换到对应分支,使远程库和本地库同步:git pull --rebase origin master
-
- 如果有冲突忽略冲突(丢弃当前补丁的重放,即忽略掉当前补丁):git rebase --skip
-
- 如果有冲突,强制推送:git push -f origin 当前分支名,如果没有冲突:git push origin 当前分支名
这里基于dev_a分支演示
本地
远程
无冲突
rebase远程master分支
推送dev_a到远程分支
远程分支内容
commit id和主分支的一样
有冲突
修改dev_a分支文件内容,并推送到远程分支
切换到master
修改master分支文件内容,然后推送到远程
切换到dev_a分支,rebase远程master,出现冲突
丢弃当前补丁的重放,即忽略掉当前补丁,变基成功并更新refs/heads/master
文件内容和master一样
dev_a远程内容
push到远程,报错
强制push到远程
远程分支内容
commit id和master一样