Git-优雅地解决冲突:使用ours和theirs

在实际的开发过程中,git冲突想必是很常见的事情,一些代码冲突可以通过进入文本编辑器,逐个手动解决冲突。但是对于rebase或者merge产生的冲突,涉及到很多文件,而且这类冲突一般是一道只保留一方的选择题。所以逐个手动解决这类冲突不太现实。

于是这今天这两位助手:--ours--theirs。这两个命令适用于both addedboth deletedboth modified等类型的冲突,通过这两个助手完整保留某一方的修改,而不用进入到文本编辑器逐行解决冲突。

在介绍两类助手之前,我们先回顾一下git rebasegit merge两类合并方式。

git merge和git rebase

假设在master主分支的基础上,有两个分支branch_abranch_b,并在各自的分支上有一些提交,当前指向的分支为branch_a,如图所示。

Git-优雅地解决冲突:使用ours和theirs

执行merge命令git merge branch_b之后,分支的状态如下图所示。Git-优雅地解决冲突:使用ours和theirs执行rebase命令git rebase branch_b之后,分支的状态如下。
Git-优雅地解决冲突:使用ours和theirs

git merge会抽取两个分支上新增的提交,并将其合并在一起,产生一个新的提交D,生成的D节点有两个父节点。其中在合并的过程中可能会发生冲突。

git rebase会以branch_a为参照,提取branch_b分支上的提交,将这些修改作用在branch_a分支上,最终结果不会产生新的提交节点。其中在将提取的修改作用在branch_a的过程中可能会发生冲突。

以我个人的经验,在开发过程中很少应用git merge合并代码,更常用的是git rebase。此外在开发过程中,经常使用git rebase命令获取master主分支的最新提交代码,在完成个人的开发任务之后,也需要rebase master分支上的代码才能申请 Pull Request,自动合并。

使用ours与theirs解决冲突

在上述两种合并中,都可能会产生冲突,需要通过手动解决。如果想要保留两个分支中的某一个可以使用git chekout --ours <fileName>或者git checkout --theirs <fileName>,这里需要注意的是,一定要知道哪个分支对应ourstheirs

直接说结论,对于mergerebase来说,这两个选项对应的分支正好是相反的。以上述示例项目为例。在使用 merge 时,ours指的是当前分支,即branch_atheirs指的是要被合并的分支,即branch_b。而在 rebase 的过程中,theirs指的是当前分支,即branch_aours指向修改参考分支,即branch_b

这么容易混淆的概念记不住? 没关系,我个人还有另一个比较直观的办法,就是直接查看冲突文件中的冲突标记。在进入冲突状态后,git会将冲突的代码用<<<<<<< ======= >>>>>>>标识出来,方便我们手动解决。在冲突标记中,=======之前表示的是ours分支,之后表示theirs分支,只需要查看某一处冲突代码即可判断出要保留的分支。

<<<<<<<HEAD

<ours contents>

=======

<theirs contents>

>>>>>>>

冲突解决步骤

git rebase合并命令为例说明解决冲突的步骤。

$ git checkout --ours <fileName>
$ git add <fileName>   //标记该冲突已解决
$ git rebase --continue 
$ git status //查看当前冲突状态
  1. 使用oerstheirs选择要保留一方的提交
  2. 标记冲突已解决
  3. 使用--continue继续执行rebase
  4. 查看冲突状态

在解决冲突过程中,如果遇到某个提交记录不需要应用,可以用下面命令忽略:

git rebase --skip

使用--abort命令可以取消本次rebase

git rebase --abort
上一篇:12. Git rebase命令


下一篇:Git rebase使用