Git 进阶系列 | 4. 合并冲突

简介: Git 进阶系列 | 4. 合并冲突

Git 是最流行的代码版本控制系统,这一系列文章介绍了一些 Git 的高阶使用方式,从而帮助我们可以更好的利用 Git 的能力。本系列一共 8 篇文章,这是第 4 篇。原文:Merge Conflicts: What They Are and How to Deal with Them[1]


合并冲突……没有人会喜欢,有些人甚至害怕冲突。但是使用 Git 时,特别是需要与其他开发人员合作时,冲突是不可避免的。大多数情况下,合并冲突并不像想象的那么可怕。在“Git 进阶”系列的第四部分中,我们将讨论冲突何时会发生,实际是什么,以及如何解决。


Git 进阶系列:

  1. 创建完美的提交
  2. Git中的分支策略
  3. 基于Pull Request实现更好的协作
  4. 合并冲突(本文)
  5. Rebase vs Merge
  6. 交互式Rebase
  7. Git中的Cherry-pick提交
  8. 用Reflog恢复丢失的提交


何时以及为什么会发生合并冲突


从名称就可以看出来: 将来自不同来源的更改集成(或“合并”)到当前工作分支时,就可能会发生合并冲突。请记住,集成并不局限于合并分支。冲突也可能发生在 rebase 或交互式 rebase 过程中、在 cherry-pick(从一个分支选择某个提交应用到另一个分支)过程中、在执行git pull时,甚至在重新加载暂存区的内容时。


所有这些操作都执行某种类型的集成,这就是合并冲突可能发生的时候。当然,并不意味着这些操作每次都会导致合并冲突,那么到底什么时候会发生冲突呢?

实际上,Git 的合并功能是其最大的优势之一: 分支合并在大多数时候都能完美工作,Git 通常能自己解决问题,知道如何集成变更。


image.png


但也有发生了相互矛盾的变化的情况,那时候技术根本无法决定什么是对的,什么是错的,这时就需要人类做出决定。例如,当同一行代码在两个不同分支的两次提交中被更改时,Git 无法知道哪一次更改才是对的。另一种不太常见的情况是,一个文件在一个分支中被修改,而在另一个分支中被删除了。Git 会问你该做什么,而不是猜测该怎么做。


image.png


怎样才能知道何时发生了合并冲突


那么,如何才能知道发生了合并冲突?不用担心,如果合并或 rebase 失败,Git 会立即告诉我们,也会对如何解决这个问题提出建议。例如,如果提交的更改与其他人的更改发生了冲突,Git 会在终端通知我们,并告诉我们自动合并失败了:


$ git merge develop
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.


可以看到,这里发生了一次冲突,Git 立即报告了问题。即使错过这条消息,也会在下次输入git status时提示有冲突。


image.png


如果使用的是 Tower 这样的 Git 桌面 GUI,会确保不会忽略任何冲突:


image.png


在任何情况下都不用担心没有注意到合并冲突!


如何撤销合并冲突并重新开始


不能忽略合并冲突,相反,必须在继续工作之前处理,基本上有以下两种选择:

  • 解决冲突
  • 中止或撤销导致冲突的操作


在开始解决冲突之前,我们简要谈谈如何撤消和重新开始(知道有可能恢复,就让人非常放心)。在很多情况下,只需要简单添加--abort参数,比方说git merge --abortgit rebase --abort,这个命令可以撤消合并/rebase 并恢复到冲突发生之前的状态。


当我们解决冲突时,即使发现自己进入了死胡同,仍然可以撤消合并。这可以给我们信心,真的不会搞砸,我们总是可以中止,返回到干净的状态,然后重新开始。


Git 中的合并冲突到底是什么样的


让我们看看真正的冲突是什么样的。是时候揭开这些小东西的神秘面纱,更好的了解它们了。一旦理解了合并冲突,就没什么可担心的了。


看看当前存在冲突的index.html文件的内容:


image.png


Git 很好的标记了文件中有问题的区域,通过<<<<<<<和>>>>>>>包围。第一个标记之后的内容来自我们当前的工作分支(HEAD),七个等号(=======)的行分隔了两个冲突的更改,后面的内容显示来自另一个分支的更改(在例子里是develop)。


我们的工作是清理这些行并解决冲突,无论是通过文本编辑器、IDE、Git 桌面 GUI,或者通过 Diff & Merge 工具。


如何解决 Git 冲突


使用哪种工具或应用程序来解决合并冲突并不重要,当完成合并后,文件看起来必须与期望的完全一样。如果只有你一个人,可以很容易决定放弃哪些更改。但是,如果有冲突的更改来自其他人,可能必须在决定保留哪些代码之前与他们进行交谈。也许保留你的,也许保留别人的,也许是这两者的结合。


清理文件并确保包含真正想要的内容的过程并不需要任何魔法,可以简单的通过打开文本编辑器或 IDE 并进行更改来做到这一点。


然而,有时这并不是最有效的方法,专用工具也许可以节省更多时间和精力。例如,在解决合并冲突时,可以利用各种各样的 Git 桌面 GUI。


以 Tower 为例,它提供了一个专用的“冲突向导”,从而使本来抽象的情况更加直观,有助于更好的理解变化来自哪里,发生了什么类型的修改,并最终解决问题:


image.png


特别是对于更复杂的冲突,手头有一个专用的 Diff & Merge 工具是很好的,通过高级功能,如特殊格式和不同的表示模式(例如并排,合并在一个列中,等等),可以帮助我们更好的理解差异。


市面上有一些 Diff & Merge 工具[2][3],可以通过git config命令配置所选择的工具(详细说明请参考工具),在冲突发生时,可以通过简单的输入git mergetool来调用。举个例子,我在自己的 Mac 上使用 Kaleidoscope:


image.png


在清理完文件后(无论是通过文本编辑器、Git 桌面 GUI,还是使用 Merge Tool),可以像提交其他更改一样提交文件。输入git add ,通知 git 冲突已经解决。


当解决了所有合并冲突并添加到暂存区(Staging Area)后,只需创建一个常规提交,这就完事儿了。


Don’t panic!


如你所见,合并冲突这件事没有什么需要担心的,当然也没有理由恐慌。一旦了解了为什么发生冲突,就可以决定是撤消更改还是解决冲突。记住,并不会产生什么破坏性后果,即使在解决冲突时意识到自己犯了错,仍然可以撤销,只需要回滚到犯错之前的提交,然后重新开始。


如果想更深入了解高级 Git 工具,可以免费查看“Advanced Git Kit[3]”: 这是关于分支策略、交互式 Rebase、Reflog、子模块等主题的短视频集合。


References:

[1] Merge Conflicts: What They Are and How to Deal with Them: https://css-tricks.com/merge-conflicts-what-they-are-and-how-to-deal-with-them/

[2] Diff tools for Mac: https://www.git-tower.com/blog/diff-tools-mac/

[3] Diff tools for Windows: https://www.git-tower.com/blog/diff-tools-windows/



目录
相关文章
|
1月前
|
人工智能 数据可视化 开发工具
Git log 进阶用法(含格式化、以及数据过滤)
Git log 进阶用法(含格式化、以及数据过滤)
|
1月前
|
开发工具 git
Git操作远程仓库及解决合并冲突
Git操作远程仓库及解决合并冲突
118 0
|
1月前
|
存储 开发工具 git
Pycharm git-创建本地仓库\创建分支\合并分支\回溯版本\加入git后文件颜色代表的含义
Pycharm git-创建本地仓库\创建分支\合并分支\回溯版本\加入git后文件颜色代表的含义
118 0
|
11天前
|
开发工具 git 开发者
【git merge/rebase】详解合并代码、解决冲突
【git merge/rebase】详解合并代码、解决冲突
29 0
|
1月前
|
JSON 开发工具 git
git rebase 合并当前分支的多个commit记录
git rebase 合并当前分支的多个commit记录
|
1月前
|
数据可视化 Go 开发工具
cggit 简化 Git 提交、合并、分支偏移小神器,提升开发、修BUG效率!
cggit 简化 Git 提交、合并、分支偏移小神器,提升开发、修BUG效率!
49 0
|
1月前
|
开发工具 git
git使用笔记-修改url并与远端库合并
git使用笔记-修改url并与远端库合并
13 1
|
1月前
|
开发工具 git
git 拉取代码仓库代码报错(合并错误 refusing to merge unrelated histories)
git 拉取代码仓库代码报错(合并错误 refusing to merge unrelated histories)
32 0
|
1月前
|
存储 开发工具 git
Git 教程:解密 .gitignore 文件、合并分支、解决冲突、及 Git 帮助
如果你忘记了命令或命令的选项,你可以使用 Git 帮助。 在命令行中,有几种不同的使用帮助命令的方式: git command -help - 查看特定命令的所有可用选项 git help --all - 查看所有可能的命令 让我们看看不同的命令。
222 3