git git pull和git pull --rebase的区别
git pull = git fetch + git mergegit pull --rebase = git fetch + git rebase现在有两个分支:test和master,假设远端的master的代码已经更改了(在B基础上变动:C,F),test的代码更改了要提交代码(在B基础上变动:D,E),如下图:D---E test/A---B---C---F--- master问题就来了,
·
git pull = git fetch + git merge
git pull --rebase = git fetch + git rebase
现在有两个分支:test和master,假设远端的master的代码已经更改了(在B基础上变动:C,F),test的代码更改了要提交代码(在B基础上变动:D,E),如下图:
D---E test
/
A---B---C---F--- master
问题就来了,如果C,F和D,E的更改发生冲突,那么就需要我们合并冲突了,下面我们来看看git merge和git rebase怎么合并的
git merge:
D--------E
/ \
A---B---C---F----G--- test, master
git rebase
git --rebase会将两个分支融合成一个线性的提交,不会形成新的节点(下面是在master上rebase)
A---B---D---E---C‘---F‘--- test, master
rebase好处
想要更好的提交树,使用rebase操作会更好一点。
这样可以线性的看到每一次提交,并且没有增加提交节点。
merge 操作遇到冲突的时候,当前merge不能继续进行下去。手动修改冲突内容后,add 修改,commit 就可以了。
而rebase 操作的话,会中断rebase,同时会提示去解决冲突。
解决冲突后,将修改add后执行git rebase –continue继续操作,或者git rebase –skip忽略冲突。
rebase详解
-
待变基分支和基分支:
- feature:待变基分支、当前分支
- master:基分支、目标分支
-
官方解释:当执行rebase操作时,git会从两个分支的共同祖先开始提取待变基分支上的修改,然后将待变基分支指向基分支的最新提交,最后将刚才提取的修改应用到基分支的最新提交的后面。
-
两个分支master和feature,其中feature是在提交点B处从master上拉出的分支,master上有一个新提交M,feature上有两个新提交C和D。
git checkout feature
git rebase master // 这两条命令等价于git rebase master feature
下图为变基后的提交节点图:
- 当在feature分支上执行git rebase master时,git会从master和featuer的共同祖先B开始提取feature分支上的修改,也就是C和D两个提交,先提取到。然后将feature分支指向master分支的最新提交上,也就是M。最后把提取的C和D接到M后面,但这个过程是删除原来的C和D,生成新的C’和D’,他们的提交内容一样,但commit id不同,feature自然最后也是指向D’
- rebase字面意思就是"变基",可以直接理解为改变基底。feature分支是基于master分支的B拉出来的分支,feature的基底是B。而master在B之后有新的提交,就相当于此时要用master上新的提交来作为feature分支的新基底。
- 注意,如果master上在B以后没有新提交,那么就还是用原来的B作为基,rebase操作相当于无效,此时和git merge就基本没区别了,差异只在于git merge会多一条记录Merge操作的提交记录。
其他案例:
- 现在假设main分支内新增的内容与你正在开发的新功能有关。
- 为了把main分支里新增的代码应用在你的feature分支,你有两种方法:merge 和 rebase
使用merge:
git checkout feature
git merge main
或
git merge feature main
- 这会在feature分支中创建一个合并提交,这次提交会连结两个分支的提交历史,在分支图示结构中看起来像下面这样
使用rebase:
git checkout feature
git rebase main
- 这些操作会把feature分支的起始历史放到main分支的最后一次提交之上,也达成了使用main分支中新代码的目的。但是,相对于merge操作中新建一个合并提交,rebase操作会通过为原始分支的每次提交创建全新的提交,从而重写原始分支的提交历史
rebase慎用场景:
场景一:
- 不要在公共分支上使用它
- 如果把main分支rebase到feature分支之上。
- 情况一:rebase命令会把main分支中的所有提交都放到feature分支的提交记录顶端。问题在于这个改变目前只出现在你的本地仓库。其他开发者仍然在原来的main分支上进行开发。由于rebase会产生全新的提交记录,所以Git会认为现在你本地的main分支与所有其他人的产生了分叉。
- 情况二:往公共分支上合代码的时候,使用merge。如果使用rebase,那么其他开发人员想看主分支的历史,就不是原来的历史了,历史已经被你篡改了。比如张三和李四从共同的节点拉出来开发,张三先开发完提交了两次然后merge上去了,李四后来开发完rebase上去(注意:李四需要切换到主分支,然后执行git rebase,然后再git push到远端),则李四的新提交变成了张三之前新提交的新基底,本来李四的提交是最新的,结果最新的提交显示反而是张三的,就乱套了
- 也就是换基底了。
更多推荐
已为社区贡献6条内容
所有评论(0)