假设master分支下有A,B,C三个commits,另外一个分支newbranch是从master的B分支checkout出去的,在newbranch已经有D,E两个commits,并且master的C commit跟newbranch的E commit存在冲突(如刚好修改到同一行),这个时候在newbranch分支下执行git rebase master的时候出现一下提示信息:
First, rewinding head to replay your work on top of it… Applying: commit from branch Using index info to reconstruct a base tree… Falling back to patching base and 3-way merge… Auto-merging README CONFLICT (content): Merge conflict in README Failed to merge in the changes. Patch failed at 0001 commit from branch When you have resolved this problem run “git rebase –continue”. If you would prefer to skip this patch, instead run “git rebase –skip”. To restore the original branch and stop rebasing run “git rebase –abort”.
这是因为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信息是线性的。