Day23|【Git】各种合并冲突与分别解决方式

了解分支的用途後,在合作开发上一定便利许多,但同样地,不是每件事情都顺顺利利,只要有合作的事情,总是会有冲突、摩擦的状况发生。在 Git 分支里,常碰到「合并冲突」的情形发生,什麽是合并冲突,又怎麽样才能解决呢?以下会慢慢讲解。


合并冲突

👉 合并冲突 - 错误讯息提示

Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

常见的合并冲突状况|

👉 合并内容同时修改同一行 code 时,就会有冲突情况。

假设今天有两位服装设计师为你打造符合你的特质的打扮,两人共同协作,但在过程中,对於其中一件配件两人彼此看法不同,例如帽子,但是你只有一个头,如果双方提供的帽子都搭上去的话,这样就会装载不下,也失去了初衷,这时候我们可以决定其中一个来做最後的选择。

同理,在一个专案中,如果有多人合作,万一改到相同的样式设定,或者改到同一行 html 结构,那麽在合并分支时,Git 就会很贴心的提醒你,现在有地方发生冲突,只要我们查看後决定要留下哪一个 code ,之後再继续提交就解决罗!

冲突范例|

  1. 先建立一个档案,针对此档案建立两个分支(master、a_branch)

    $ mkdir demo # 建立一个 demo 资料夹
    $ cd demo # 进入 demo 资料夹
    $ git init # 建立数据库
    $ touch index.html # 新增一个 index.html 档案
    $ git add . # 加至暂存区
    $ git commit -m"update index.html" # 提交至储存库
    

    https://ithelp.ithome.com.tw/upload/images/20211005/20141010QlecCwpjNw.png

    提交完成後,我们另外建立一个分支:git branch a_branch

    https://ithelp.ithome.com.tw/upload/images/20211005/20141010071wEIgqL1.png

  2. 建立完两个分支後,分别在两个分支的状态对这个 index.html 档案做修改并提交版本。

    首先是 master 分支:

    https://ithelp.ithome.com.tw/upload/images/20211005/201410105NlpUNotsw.png

    // 档案修改完後,加至暂存区并提交
    $ git add . # 加至暂存区
    $ git commit -m"讯息记录" # 提交至储存库
    

    https://ithelp.ithome.com.tw/upload/images/20211005/20141010UzbbTvADOL.png

    再来切换到 a_branch 分支,修改 index.html 档案。

    https://ithelp.ithome.com.tw/upload/images/20211005/201410100OgPN3rQSW.png

    https://ithelp.ithome.com.tw/upload/images/20211005/20141010xa6ndqZxM6.png

    一样要记得加至暂存区并提交

    https://ithelp.ithome.com.tw/upload/images/20211005/20141010ha7sHTDgm9.png

  3. 现在试着将 master 分支与 a_branch 分支合并:

    $ git merge a_branch # 在 master 分支上合并 a_branch 分支
    

    https://ithelp.ithome.com.tw/upload/images/20211005/20141010tjKPPwO6A6.png

    错误讯息!合并发生冲突了!

解读冲突讯息

Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Auto-merging index.html - git 正在自动合并 index.html 档案。

CONFLICT (content): Merge conflict in index.html - 合并冲突的种类属於内容冲突 CONFLICT (content)

Automatic merge failed; fix conflicts and then commit the result. - 自动合并错误,请修复冲突的地方,再来进行 commit 动作。


解决方法

解决流程|

  1. 发现合并冲突讯息
  2. 使用 git status 指令查看状态
  3. 打开有错误的档案(GIt 会很贴心的帮你找出错误的那一行 code )
  4. 修改 - 留下最後需要的 code
  5. 使用 git add 指令将修改後的档案加回暂存区
  6. git commit 指令继续提交新的版本到储存库

🛠 实际操作范例|

首先发现有冲突提示:

https://ithelp.ithome.com.tw/upload/images/20211005/20141010PROuiNVxTW.png

使用 git status 指令查看状态

$ git status # 查看状态

https://ithelp.ithome.com.tw/upload/images/20211005/20141010EAs3zgjZL6.png

both modified: index.html

打开有错误的档案,可以看到 Git 有贴心的帮你指出哪边发生冲突

https://ithelp.ithome.com.tw/upload/images/20211005/20141010GKgLnhnwfm.png

将冲突的地方修改,选择留下最终要的那个 Code

https://ithelp.ithome.com.tw/upload/images/20211005/20141010CAnZUhQNGy.png
最後才重新加至暂存区,并提交,最後就完成这次合并的动作罗!

$ git add . # 加至暂存区
$ git commit -m"讯息记录" # 提交至储存库

https://ithelp.ithome.com.tw/upload/images/20211005/20141010Qn1rHHmpHP.png


使用 Rebase 合并时遇到冲突

只要是档案之间有沟通不良情形,就会打架,即使是使用 Rebase 指令合并,也会有合并冲突的情形发生。但是使用 Rebase 指令合并发生冲突时,它的过程跟一般合并不一样的地方在於:执行过程卡住。

这部分可以使用 SourceTree 有分支图示会更好理解喔!

解决方式|

跟上面提过的解决方式一样,当我们发现错误讯息时,首先使用检查状态指令,查看哪个地方出问题,後续再修改,修改完毕後再继续执行指令,就可以完成提交罗!

👉 流程大概:
发现错误讯息
git status 找到问题点
→ 修改
git add 加回暂存区
git rebase --continue


非文字档的合并冲突

$ git checkout --ours [档名] // 如果决定使用当前分支的档案
$ git checkout --theirs [档名] // 如果决定使用对方的档案

先前提到的档案合并大多都是文字档案,Git 就可以使用标记的方式告诉我们哪里出错,但有时候会遇到例如图片档之类的二进位档,这时候就会难以使用肉眼的方式发现冲突的地方。

解决方式|

查看错误讯息提示

决定要使用哪个分支的档案作为最後的选择

根据当前的分支,来决定使用的参数 --ours / --theirs

git add 指令加回暂存区

git commit 指令提交至储存库


<<:  Day 25 强度与深度

>>:  [Day 22] 阿嬷都看得懂的元素容器与隐藏空格解法

[C 语言笔记--Day25] fork() 的小小练习

#include <unistd.h> #include <stdlib.h>...

Day-27 特集:测试驱动开发 TDD

所谓测试驱动开发(Test-driven development, TDD),即「先写测试再开发」,...

Thunkable学习笔记 3 - 读取Realtime Database的值(Firebase)

於Realtime Database内手动建立如下图的资料, 试着使用thunkable读取, 测试...

完结心得

比起去年,今年给我更大的冲击与感触,不光是因为团体赛没有达标,而是因为挑战的过程中,与当初设想的情境...

DAY17 服务室--JSON Server 部属

前言 因为 JSON Server 没有验证的功能,所以只适合让我们拿来做作品集使用,可以简单的让我...