冲突的产生
很多命令都可能出现冲突,但从根本上来讲,都是 merge 和 patch(应用补丁)时产生冲突。
而 rebase 就是重新设置基准,然后应用补丁的过程,所以也会冲突。
git pull 会自动 merge,repo sync 会自动 rebase,所以这两个也会产生冲突。
解决 merge/patch 冲突
git merge
命令用于合并指定分支到当前分支。
假设某一时刻 master 和 feature1 分支是同步的,文件 a.txt 内容如下:
Git is a distributed version control system.
Creating a new branch is quick.
然后在 feature1 上修改了最后一行并提交了:
Creating a new branch is quick AND simple.
切换到 master 分支,也修改了最后一行并提交了:
Creating a new branch is quick & simple.
现在,master 分支和 feature1 分支各自都分别有新的提交,变成了这样:
这种情况下,Git无法执行“快速合并”(快速合并,就是当 Git 发现某一个分支的修改是基于另一个分支的最后一次提交时,会直接指向当前提交),只能试图把各自的修改合并起来,但这种合并就可能会有冲突:
$ git merge feature1
Auto-merging a.txt
CONFLICT (content): Merge conflict in a.txt
Automatic merge failed; fix conflicts and then commit the result.
git status
可以告诉我们冲突的文件:
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
# Unmerged paths:
# (use "git add/rm ..." as appropriate to mark resolution)
#
# both modified: a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
直接查看 a.txt 的内容会发现,Git 已经用 <<<<<<<,=======,>>>>>>> 标记出了不同分支的内容:
Git is a distributed version control system.
<<<<<<< HEAD
Creating a new branch is quick & simple.
=======
Creating a new branch is quick AND simple.
>>>>>>> feature1
这时就需要我们手动修改并提交了,例如保留 master 的修改:
Git is a distributed version control system.
Creating a new branch is quick & simple.
再提交:
$ git add a.txt
$ git commit -m "conflict fixed"
[master 59bc1cb] conflict fixed
冲突解决。现在,master 分支和 feature1 分支变成了下图所示:
同理,使用 git am
应用补丁产生冲突时,手动解决然后提交。
rebase 的冲突解决
git rebase
的冲突解决过程,就是解决每个应用补丁冲突的过程。解决完一个补丁应用的冲突后,执行 git add -u
命令标记冲突已解决(也就是把修改内容加入缓存):
-u 表示把所有已 track 的文件的新的修改加入缓存,但不加入新的文件。
然后执行 git rebase --continue
继续 rebase。有冲突继续就重复这这些步骤,直到 rebase 完成。