本随笔介绍Git系统中,文本文件和二进制文件在合并分支时发生冲突的解决方式。本随笔是基于Git v2.33.0版本编写,过旧或者过新的Git版本可能不会对本随笔提到的命令做出正确的反应。

随笔作者还在学习阶段,对Git软件的理解和使用还不是非常透彻,难免会出现技术上或书写上的问题,若出现了类似的问题欢迎在评论区或者私信讨论。

合并文件时发生冲突的解决方式

当我们进行合并分支操作,并且该次操作相关的文件存在冲突(无论是文本文件还是二进制文件),则此次合并操作会失败,并且会在相应的冲突文件内容里打上冲突标记(仅限于文本文件,其他文件不会有任何修改),并让Git系统进入冲突状态,想要解决冲突状态,有多个选项可以选择。

退出冲突状态

如果不想进一步处理冲突,而是希望系统能够回到发生合并冲突之前的状态,则可以使用命令git merge --abort来中断(Abort)此次冲突及合并操作,只要在发生冲突到执行该命令的时间段里都保持工作区干净的话则可以轻松地返回到执行合并操作之前的状态。

运行合并工具(仅适用于于文本文件)

该操作仅限于文本文件
要想处理当前冲突,可以运行命令git mergetool来启用合并工具,我使用的合并工具是“vimdiff”,启用之后终端上会打开上下两行,上行三个窗口,下行一个窗口,共四个窗口:
Git学习笔记:文本文件和二进制文件合并时冲突的解决方式_Git
从名字上可以知道,上行左数第一个窗口是是我们本地分支(即当前所在分支)的文件内容,第二个是共同祖先(Common Ancestor)分支的文件内容,第三个是远程分支的文件内容,下行的窗口就是被合并后的文件内容,可以看到已经被打上冲突标记。在该窗口下可以通过几个vim命令来修改合并后的文件内容,首先把光标移动到冲突标记范围内:
:diffg 1:将冲突内容替换为本地分支上的内容。
:diffg 2:将冲突内容替换为共同祖先分支上的内容。
:diffg 3:将冲突内容替换为远程分支上的内容。
上述命令中的1、2、3分别代表着本地分支、共同祖先分支和远程分支。

修改完成之后用通用的vim命令来保存文件并退出,则视为该冲突已经被解决,但是目前Git仓库里并没有解决后的提交记录(如果在合并的时候没有发生任何冲突,则Git系统会自动发起一个正常的提交请求),所以我们需要使用命令git commit来提交这一次合并完成之后的文件内容。

用本地分支或者远程分支的文件直接替换冲突文件(文本文件、二进制文件都可使用)

要是提前知道了文件内容需要完全被替换掉,而不需要一个冲突点一个冲突点地去检测,则可以在发生冲突之后(不要运行合并工具)使用命令git checkout --ours|--theirs <Paths>来选择是使用“我们的(Ours,即本地分支)”版本的文件还是“他们的(Theirs,即远程分支)”来直接替换掉冲突文件,其中<Paths>是冲突文件的路径。

如果想要在合并开始之前就指定当合并发生冲突的时候直接使用本地分支或者远程分支的文件替换掉冲突文件而不需要处理冲突部分(尤其适用于二进制文件),可以在执行合并命令的时候添加上指定本地或远程分支的选项来实现直接替换的功能:git merge -Xours|-Xtheirs <BranchName>,注意参数中的X是大写。在合并的时候添加上这个参数,即可在合并发生冲突的时候直接用指定分支的文件覆盖掉冲突文件,之后需要做的事情就仅仅只是填写合并提交信息即可。