git-merge命令是用于从指定的commit(s)合并到当前分支的操作。
注:这里的指定commit(s)是指从这些历史commit节点开始,一直到当前分开的时候。
git-merge命令有以下两种用途:
假设下面的历史节点存在,并且当前所在的分支为“master”:
那么git merge topic命令将会把在master分支上二者共同的节点(E节点)之后分离的节点(即topic分支的A B C节点)重现在master分支上,直到topic分支当前的commit节点(C节点),并位于master分支的顶部。并且沿着master分支和topic分支创建一个记录合并结果的新节点,该节点带有用户描述合并变化的信息。
即下图中的H节点,C节点和G节点都是H节点的父节点。
一、开发分支(dev)上的代码达到上线的标准后,要合并到 master 分支
git checkout dev
git pull
git checkout master
git merge dev
git push -u origin master
二、当master代码改动了,需要更新开发分支(dev)上的代码
git checkout master
git pull
git checkout dev
git merge master
git push -u origin dev
git merge的冲突判定机制如下:
先寻找两个commit的公共祖先,比较同一个文件分别在ours和theirs下对于公共祖先的差异,然后合并这两组差异。
如果双方同时修改了一处地方且修改内容不同,就判定为合并冲突,依次输出双方修改的内容。
master分支上有一个1.txt文件,进行修改后提交
$ cat 1.txt
1
11
12
$ echo 13 >> 1.txt
$ git commit -a -m "modified 3.txt,add 13 in the end"
[master 4850577] modified 3.txt,add 13 in the end
1 file changed, 1 insertion(+)
test1分支是基于未修改的1.txt创建的,切换到test1分支上,修改1.txt并提交
$ git checkout test1
$ cat 1.txt
1
11
12
$ echo 133 >> 1.txt
$ git commit -a -m "add 133 in the end"
[test1 2856268] add 133 in the end
1 file changed, 1 insertion(+)
可见,两次对1.txt的修改是不同的。在test1上的merge过程如下:
$ git merge master
Auto-merging 1.txt
CONFLICT (content): Merge conflict in 1.txt
Automatic merge failed; fix conflicts and then commit the result.
$ git status
On branch test1
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add ..." to mark resolution)
both modified: 1.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ cat 1.txt
1
11
12
<<<<<<< HEAD
133
=======
13
>>>>>>> master
如上所示,系统提示了1.txt的冲突。
开始修改。
vi 1.txt #删除冲突字符及修正冲突文本
$ cat 1.txt
1
11
12
133
13
git commit -a -m “modified 1.txt,add 133 & 13 in the end”
冲突解决结束。push即可。
git merge是按照修改顺序来合并的,而不是内容覆盖。
比如,mynotes分支是基于master分支checkout的。
修改前,test20200711_2.txt内容为:
update repo from Github.
切换到mynotes分支,修改test20200711_2.txt内容为:
update repo from Gitee.
git commit后, git merge master, 并不会将master的老内容覆盖到mynotes上。
此时,mynotes上test20200711_2.txt内容为:
update repo from Gitee.
切换到master分支, git merge mynotes会将mynotes修改的内容合并到master上。
此时,master上test20200711_2.txt内容为:
update repo from Gitee.