某天同事小L找我帮忙解决代码冲突引起的问题,折腾一番之后,问题解决了。场景是他想把最新的主干分支代码合并到当前开发分支上,解决掉冲突,然后提交推送到远程。他合并代码的过程是:
git fetch origin master
git merge origin master
第一句是更新远程master分支代码,第二句看着像是合并远程分支master代码到当前分支。因为我平时都是切换到master分支,git pull,然后切换到自己开发分支,再git merge master,对前面的用法不太熟悉。翻看教程的时候,对于前面那种场景使用的是git merge origin/master,心中难免有些疑惑,这两种用法一样么?
之后从网上简单搜索了下,看到几篇文章也在说这两种用法的区别,大概有两种解释,一种认为两种用法一样;一种认为如下:
git merge origin master //将origin merge 到 master 上
git merge origin/master //将origin上的master分支 merge 到当前 branch 上
网上持有第二种观点的人不在少数,我开始也信了,还截图告诉小L,以后使用git merge origin/master。但是之后回想起来,又感觉有些不妥:如果小L之前一直使用git merge origin master的话,按照网上的解释是达不到预期效果的,应该早就发现有问题了。那究竟这两种用法有什么区别呢?
于是我自己创建了一个git仓库,来模拟这种场景。结果发现两种用法,似乎效果一样。然后各种查阅资料,同时也在老外的一篇帖子上看到了这种说法:
All parameters to ‘git merge’ in this case are branches that you’re merging from, i.e. source branches. You’re always merging to the current branch.
Because origin is a remote name, git automatically expands it to that remote’s default branch, so it’s actually equivalent to origin/master – the command is being told to merge the same branch twice.
(It is possible to merge more than one branch, known as “octopus merge”, but this is rarely done – and when it is done, the branches of course are different.)
As it is, the command doesn’t make much sense. Maybe it should have been either git merge origin/master (without the duplication) or git pull origin master.
这个说法我比较认可。但是怎么验证呢?假设我当前分支为branchA,于是我又新建了一个分支branchB,通过手动修改,使得远程master和本地branchB分支的代码均与当前分支有差异,现在想把远程master分支代码和本地branchB分支代码合并到当前分支:
git fetch origin master
git merge origin branchB
然后查看代码,发现远程master的变更和本地branchB的变更都合并到当前分支上了。这里的origin指的是远程库,因为没写具体名字,所以指向默认分支master,实际上等同于:
git merge origin/master branchB
大家查看Git帮助文档:git merge --help就可以发现:
git-merge - Join two or more development histories together
git merge可以合并多个分支,即该命令后面可以跟多个分支的名字,都是将这些分支的变更合并到当前分支。所以网上说的git merge origin master是把origin merge 到 master 上的说法是错误的,实际是把远程分支master在本地的副本以及本地分支master合并到当前分支。其实直接使用git pull origin master更简洁,相当于git fetch origin master和git merge origin/master。