关于no branch , rebasing master问题解决

我在执行git branch 这条命令时,下面出现no branch , rebasing master ,我的代码没有在分支中,碰到这种情况需要了解merge和rebase的区别。

假设master分支下有A,B,C三个commits,另外一个分支newbranch是从master的B分支checkout出去的,在newbranch已经有D,E两个commits,并且master的C commit跟newbranch的E commit存在冲突(如刚好修改到同一行),这个时候在newbranch分支下执行git rebase master的时候出现一下提示信息
这是因为master分支上最后一个commit跟当前分支(newbranch)的最后一个commit存在冲突,git不能自动完成rebase当前分支到master分支的最后一个commit,这个时候执行git branch发现当前的分支是*(no branch)。根据上面的提示信息,我们要人工解决冲突,使用git mergetool解决完冲突后,使用git commit -am ‘message’提交,再然后用git rebase –continue完成rebase。

之后可以执行git checkout master回到master分支,执行git merge newbranch把newbranch合并到master分支,这个时候不会有任何冲突,会出现“Fast-forward”(即“快进”,对于这种合并,git内部不需要做任何真正的merge,只需要直接将HEAD指针由原来master的C位置移到newbranch的E位置,当然,这个时候所谓newbranch的E位置已经是master的E了,因为已经把newbranch合并到master了),直接合并成功,并且执行git log –graph可以看到master分支上的所有提交都是线性的(linear),尽管从log信息我们看到了来自newbranch的commit,这个也是rebase区别于merge的地方。

关于最后在master分支下执行git merge newbranch再详细说一下为什么git在这个时候可以Fast-forward。

因为在newbranch分支下执行git rebase master之后,newbranch的base commit就已经是master的C commit了,而不是原先的B commit,所以当最后回到master分支之后,再执行git merge newbranch,git知道这个不可能会有冲突的,所以只需要Fast-forward就可以了。也是由于Fast-forward的原因,最后的git log信息是线性的。

下面讲述一下merge 和rebase的区别
merge的合并是三方合并,并且历史版本号都在本地方库中,可是却比較繁琐,并且开发的过程是个网状结构,假设创建的分支比較多,进行的merge也比較多,那么就算我们在纸上画它的提交历史都会画的手疼,可是rebase就不一样,它是依据另外一个分支的改动内容进行打补丁然后在前一个分支的最后提交上进行改动,并且将另外一个分支的提交历史删除,这样就是一个线性的过程,非常清晰。所以在推送到远程仓库之前尽量多用rebase来衍合分支,可是假设将一个commit推送到远程仓库之后,就不要再对它进行衍合操作了,由于这种话,它非常可能在你的某次衍合过程中被删除,那么再推送到远程仓库就会造成非常大的损失。切记,rebase虽好可不要贪杯。rebase除了 --continue外,还有 --skip 和 --abort 操作,其中skip会忽略自己的提交,而更新为远程仓库版本;abort会放弃本次合并操作,回到rebase之前的状态。

你可能感兴趣的:(git)