Skip to content

Git 合并与冲突

Git 合并与冲突

简介

分支合并

Git 分支合并是将两个不同的分支中的代码合并到一个分支中的过程。在软件开发中,分支合并是一种常见的操作,允许开发团队在不同的开发线上并行工作,并将最终的更改整合到主要的代码库中。

冲突

在并行工作的模式下,工作最终会发生重叠。当多个成员以不同的方式更改同一行内容时,在这种情况下,Git 无法判断哪个版本是正确的,这时就会产生冲突。

比如多个分支代码合并到一个分支时,或者多个分支向同一个远端分支推送代码时。

$ git merge change_site
Auto-merging filename
CONFLICT (content): Merge conflict in filename
Automatic merge failed; fix conflicts and then commit the result.

应用场景

在一个项目中,一般会有主分支,比如叫做 Master 分支或者 main 分支。master 分支是 Git 默认创建的分支,因此基本上所有开发都是以这个分支为中心进行的。主分支上的是通过测试的、可用的稳定代码。

然后项目中的成员会在主分支的基础上,创建自己独立的分支,完成不同的内容修改。这就是我们进行项目协作最常用的方式。

在实际工作中,每个人操作的分支进度都不一样。通常情况下在开发完毕之后,大家都是基于自己当前的分支向 master 提出合并请求,如果自己的分支领先 master 分支领先于 master,直接提出 merge request 即可,进行合并;

但如果分支又有落后又有领先呢,就需要先把别人已经推送至 master 的提交,先同步合并至本地。

所以这里就涉及到了两种场景。

第一是把主分支中的内容合并到自己的分支中。因为刚才说过主分支里的是稳定的可用版本的内容。我们需要定时的把这些最新的稳定内容和自己分支中的内容进行合并,以保证自己的分支中包含最新的内容。

这样做了,我们后期把自己分支合并入主分支的时候,就捕容易遇到冲突。

那第二种就是我们在自己的分支上完成对应修改后,提交任务就需要把自己的分支的内容合并到主分支里面。这种时候一般就需要通过提 Merge Request 的方式,让项目负责人审核这次提交是否符合要求。通过之后再合入主分支。

这就是在实际工作中合并分支的两个最主要的场景。

操作步骤

合并分支

  • 合并指定分支到当前分支:
    • git merge 其他分支 本分支
  • 变基:重新设置基准:
    • git rebase 其他分支

首先是 merge,字面意思就是合并。

如下图所示就是 merge 的场景。这里是从 master 分支上新拉出来一个分支,做了一些修改,然后又合并到了 master 分支中。

这个场景中,master 分支从 2 提交节点分别引出 bugfix 和 dev 的分支,并且分别前进了 3,4,5,6 的提交,这时候想从 dev 拿到 bugfix 分支的代码,就在 dev 分支上执行 merge 命令。

这时候会执行的操作就是,对 dev 的头部提交、bugfix 的头部提交、两个分支最近起始点,进行一个三方合并,做出差异对比形成一个单独的 commit 进行提交,置于当前分支的头部,此时在使用 git log 时也能看到 3456 的提交,但真正起作用的只有最后一次提交。这就是 merge 的过程。

还有一种合并方式是使用 rebase。rebase,字面是变基的意思。过程如下图所示:

分析一下这个过程,执行 rebase 之后, 其实做的就是找到两个分支的最近起始点,将起始点之后的被合并分支提交先拿掉,将合并分支 bugfix 起始点之后的所有提交在当前分支“重现一遍”,之后把当前分支所有提交(5,6)在后面进行差异提交。

而由于 5,6 之前是分别在 2,5 的基础上进行的提交,而当前的 dev 的提交则不一样了,因此 5,6 就会变成 5’,6’。因此我们可以看到,当前的 dev 分支,比 rebase 之前的分支,基础被变了,这个变基的命名还是挺形象的,dev 的历史都被修改了。

变基操作使分支提交历史相对 merge 很漂亮简洁,但会修改历史。这会导致什么呢?

你当前本地 dev 的分支的历史与远程的 5-6 历史不一致,导致远程不认识,因此无法提交至远程。

而如果你把这个提交强行合并到远程,跟你一起在 dev 上工作的伙伴们并没有误操作,但是就是提示历史有变动,dev 有问题。因此我们对于公共分支即共同开发的分支,尽量不要使用变基。

解决冲突

  • 解决冲突方式:
    • IDE 中解决冲突:选择要保留的内容点击 Accept,保存代码。
    • 文件中解决冲突:保留需要的内容,删除其余内容,去掉分割线,保存代码。
  • 冲突解决流程:
    1. 在本地当前分支上,修改冲突内容。
    2. 执行 git add . 添加到暂存区。
    3. 执行 git commit -m '提交说明' 提交到本地仓库,完成合并。
    4. 执行 git push 提交到远程仓库。
<<<<<<<
(本地修改内容)
=======
(远程修改内容)
>>>>>>>

总结

  • 什么是冲突
  • 应用场景
  • 合并分支
  • 解决冲突