合并(merge)是很常用的操作。尤其是一个庞大的很多人参与开发的企业级应用。一般会设定一个主分支,和多个副分支。
在副分支开发完成后,合并到主分支中。始终保持主分支是一个完整的,稳定的最新状态的分支。
那么合并必然带来一些问题,比如最常见的冲突问题。
合并冲突
首先初始化一个仓库用于测试合并的冲突问题。建立一个文件,内容如下:
文件内容:
this is the 1 line.
this is the 2 line.
this is the 3 line.
this is the 4 line.
this is the 5 line.
将文件加入缓存,然后提交。
这时在当前分支基础上,切换到新的分支whitespace,修改第三行。文件内容如下
this is the 1 line.
this is the 2 line.
this is the 3 line. Changed.
this is the 4 line.
this is the 5 line.
将这个文件也提交。然后确认一下两个分支的状态。
$ git log
commit f707a64fe9e2b39bd60be414eb11c61f8e811bc1 (HEAD -> master)
Author: kutilion <kutilion@gmail.com>
Date: Fri Apr 12 17:51:51 2019 +0800
1st commit
$ git log
commit 699ea51361645afa83d871be47518cc14b52ea4c (HEAD -> whitespace)
Author: kutilion <kutilion@gmail.com>
Date: Fri Apr 12 17:56:26 2019 +0800
1st commit on whitespace branch
commit 96b5bc8cb0a8e71099a4e2908e8dc1256e0c0dd6
Author: kutilion <kutilion@gmail.com>
Date: Fri Apr 12 17:51:51 2019 +0800
1st commit
现在返回master分支,修改master分支下的文件,内容如下。
this is the 1 line.
this is the 2 line.
this is the 3 line. Conflicted.
this is the 4 line.
this is the 5 line.
这时, 两个分支的第三行已经产生了冲突。执行合并操作会出现错误:
$ git merge whitespace
Auto-merging MergeTest.txt
CONFLICT (content): Merge conflict in MergeTest.txt
Automatic merge failed; fix conflicts and then commit the result.
冲突的文件内容:
this is the 1 line.
this is the 2 line.
<<<<<<< HEAD
this is the 3 line. Conflicted.
=======
this is the 3 line. Changed.
>>>>>>> whitespace
this is the 4 line.
this is the 5 line.
确认一下分支状态,也可以看到冲突提示。
$ git status -sb
## master
UU MergeTest.txt
取消这次失败的merge可以使用如下命令
$ git merge --abort
再次确认分支状态,发现冲突提示没有了。回复到了合并前的状态。但是要注意,如果当前分支由未被追踪的文件,可能会被删除。
$ git status -sb
## master
当然,也可以使用reset –hard HEAD命令来强行返回合并前的状态。
手动合并文件
出现冲突后,可以手动解决。这时需要确认三个版本的文件,执行合并命令的分支的文件,被合并分支的文件,以及它们共通的先祖文件
可以使用show命令把这三个文件拷贝出来
$ git show :1:MergeTest.txt > MergeTest.ancestor.txt
$ git show :2:MergeTest.txt > MergeTest.master.txt
$ git show :3:MergeTest.txt > MergeTest.whitespace.txt
官网推荐使用merge-file命令和上述三个文件来合并。但是笔者不推荐,笔者推荐直接手动修改冲突文件,然后再次提交。
$ git add MergeTest.txt
$ git commit -m "Merge conflict solved"
[master d102b7c] Merge conflict solved
确认解决后的合并状态
$ git log --oneline
47e0c00 (HEAD -> master) Merge conflict solved
1bc9fcc 2st commit on master branch
77fbf54 (whitespace) 1st commit on whitespace branch
efbb750 1st commit on master branch