如何解决Git中的合并冲突--带实例的实用指南

178 阅读9分钟

Git 是一个开源的分布式版本控制系统。它帮助你使用本地分支、暂存和工作流程轻松管理你的项目文件。

今天,许多开发者都在使用Git。而且他们通常都很熟悉Git的基本概念,比如:

  • 如何启动一个仓库
  • 如何创建分支
  • 如何进行阶段性/非阶段性修改
  • 如何提交更改
  • 如何将提交内容推送到远程

然而,许多开发者对mergingresolving merge conflicts 这样的概念感到困惑。在这篇文章中,我们将学习如何以一种实用的方式解决合并冲突。这意味着你将在阅读、理解和尝试的同时,通过这篇文章。

如果你也喜欢从视频内容中学习,这篇文章也可以作为视频教程放在这里: 🙂

如果你是Git的新手,想学习所有的基本概念,这里有一个有用的速成课程

开发人员对 "合并冲突 "是怎么说的?

最近我在Twitter、LinkedIn和YouTube上做了一个调查,询问开发者对解决Git中的合并冲突是否感到满意。你猜我发现了什么?

70%-80%的开发者分享说,他们认为在Git中解决合并冲突很有挑战性。所以这意味着 "解决合并冲突 "是一个重要的讨论话题。

poll

投票结果 - 你对解决Git中的合并冲突感到满意吗?

什么是Git合并,什么是合并冲突?

Git 是一个版本控制系统,它保留了你所有文件版本的历史。你可以在任何时候回到任何一个版本,并取回一个较早的版本。

假设你创建了一个名为abc.txt 的文件,并将其推送到 Git 仓库。此时,该文件有其当前的版本与之相关。现在,如果你的同事修改了同一个文件,并将其推送回仓库,该文件就有了新的版本。

Git Merge 是一个允许你将文件的当前内容与其他以前的版本保持同步的功能。这一点至关重要,因为任何人在任何时间点都应该在文件的最新内容上工作,而不会覆盖以前版本的任何变化。

Gitmerge 可以帮助你在向同一文件推送新的改动之前,合并来自其他开发者的改动。

image-46

在Git合并的情况下,我们需要注意两件事:

  1. 更改:一个文件的两个版本之间发生了什么类型的操作?新的内容被添加或删除,或者现有内容被更新。
  2. 可能性:有两种可能性。变化发生在文件的different regions ,或者变化发生在文件的same region 。同一区域意味着开发者围绕文件的同一位置(例如段落、行等)进行了修改。

幸运的是,Git使用auto-merge 策略自动处理了大多数这种情况。但当修改发生在文件的same region ,Git就不会执行自动合并了。取而代之的是,它让你去Resolve the Merge Conflicts

Git 合并冲突:一个恐怖的故事

让我们通过两个开发人员Alex和Tina的故事来理解上述情况。

在一个美好的日子里:

  • Alex 把远程仓库的修改拉到他的本地仓库。
  • 他修改了名为abc.txt 的文件,将其暂存,提交,最后推送回远程版本库。
  • 与此同时,Tina 不知道 Alex 对abc.txt 文件的修改,她对该文件的same region 做了一些修改,并试图将其推送到远程版本库。
  • Git 是一个版本控制系统,所以它警告蒂娜,她修改的版本比远程中的版本要早(因为Alex的修改已经在远程中)。
  • 现在,Tina需要先从远程拉出修改,更新文件,然后再尝试推送。
  • 蒂娜这样做了。然而,在她最疯狂的噩梦中,她得到了警告:auto-merge 失败,所以她现在需要Resolve the merge conflicts

image-45

这个故事有什么印象吗?上述故事与你有关吗?有可能你过去也曾遇到过蒂娜的情况。如果没有,你最终会到达那里的!那么,让我们来了解蒂娜如何有效地处理这种情况。

如何解决Git中的合并冲突

解决合并冲突并不像它听起来那么棘手。在90%的情况下,一旦你对变化有了清晰的认识,并有一个平和的心态,就会比较容易。

思考过程

一旦 Tina 拉取了修改,Tina 的本地文件就有了她的修改和 Alex 的修改。现在Tina可以做这四件事中的一件:

  • 她可以保留亚历克斯的修改并删除她的修改。
  • 她可以删除Alex的修改并保留她的修改。
  • 她可以同时保留Alex的和她的修改。
  • 她可以同时删除亚历克斯的和她的改动。

好吧,但是她应该做哪一个呢?这完全取决于项目的需求和使用情况。Tina会理解incoming ,并做任何与情况相关的事情。

那么,什么是incoming 变化?蒂娜要如何识别?Tina如何做出改变?我知道你有很多这样的问题。让我们通过下面一节中的几个真实的例子来获得所有的答案。

解决Git中合并冲突的步骤

让我们举几个现实生活中的合并冲突的例子,并学习如何解决它们。

在任何时候,如果你想交互式地学习这些概念,请查看我在本文开头提到的视频的这一部分

例子 1: 更改在文件的同一区域内

当Git因为更改在同一区域而无法执行自动合并时,它会用特殊的字符表示冲突的区域。这些字符序列是这样的。

  • <<<<<<<
  • =======
  • >>>>>>>

<<<<<<<======= 之间的所有内容都是你本地的修改。这些修改还没有在远程版本库中。=======>>>>>>> 之间的所有行都是来自远程版本库或其他分支的修改。现在你需要研究这两个部分并做出决定。

下面的图片显示了一个文件的内容,表明自动合并没有发生,存在冲突。冲突发生在我们在本地修改了文件的那一行,即添加了一行- Sleep 。但与此同时,其他人在同一区域添加了一行- Gym ,从而推送了一个修改。

因此,- Sleep 这一行被标记为本地修改,而- Gym 则是来自远程仓库或另一个分支的修改。

merge-conflict

由于同一区域内的修改而产生的合并冲突

根据你的用例和项目需要,你将决定如何解决这个冲突。如果你只需要保留带有- Sleep 的那一行,你将保留它并删除其余冲突的文本。在这种情况下,文件内容就变成了:

- Eat
- Read
- Sleep

相反,你可以保留- Gym 这一行,并删除- Sleep 的修改:

- Eat
- Read
- Gym

如果你需要保留这两行,请删除与冲突指标有关的行:

- Eat
- Read
- Sleep
- Gym

如果你认为这些修改都不需要,就把它们全部删除:

- Eat
- Read

完全由你来决定哪些修改是与情况相关的。在你的修改之后,你需要确保文件中没有任何冲突指示字符存在(<<<<<<<, =======, >>>>>>>)。一旦你解决了这些变化,请做以下工作。

将这些修改归档:

git add <files>

提交修改,并写上信息:

git commit -m "Message"

最后,将修改推送到远程:

git push

这就是解决这种情况下的合并冲突的全部方法。

例2:文件在远程/其他分支被删除了

在移除文件的合并冲突中,一个开发者在一个分支中删除了一个文件,而另一个开发者在另一个分支中编辑了同一个文件。在这种情况下,你需要决定是否要保留这个文件,或者删除它是否正确。

要把被删除的文件加回你的分支,请这么做:

git add <file-name>

如果要继续删除该文件,请这样做:

git rm <file-name>

然后提交你的修改,并写上信息:

git commit -m "Message"

最后,推送它:

git push

下一步是什么?

如果你从以上两个例子中学习并实践,你将能够处理大多数情况并解决你的合并冲突。所以,我建议对它们进行几次练习。

如果你面临任何新的情况,或在解决合并冲突时被卡住,请随时在本视频的评论区发表评论。我将尽我所能给予回复。

在我们总结之前,有几个提示给你:

  • 本文所展示的所有例子都假设你使用GitBash或其他Git CLI来解决合并冲突。你可以使用任何其他GUI工具来做同样的事情。
  • 在开始对代码进行任何新的逻辑工作之前,一定要从远程/其他相关分支拉取。这将使你的分支尽可能地保持最新状态,并减少冲突的机会。
  • 总是在推送之前拉取,以确保你不会面临任何来自 Git 的拒绝。
  • 当你无法决定什么该保留,什么该删除时,请与你的同伴/合作开发者讨论。结伴解决任何困难的合并冲突。

现在就说这么多。我希望你能发现这篇文章的信息量和洞察力,以帮助你解决Git中的合并冲突。

让我们联系起来:

  • 如果你不想错过每天的网站开发和编程技巧,请在Twitter上关注我们。
  • GitHub上查看我的开放源代码项目。
  • 如果你想学习JavaScript、ReactJS、Node.js、Git,以及所有关于Web开发的实用方法,可以订阅我的YouTube频道。

我的下一篇文章很快就会与你见面。在那之前,请照顾好自己,并保持快乐。