文章学习自:麦兜搞IT,如有侵权,告知删除
文章目录
- 前言
- 1 Fast Forword 合并
- 1.1 核心原理
- 1.2 举个栗子
- 1.3 经验之谈
- 2 three way merge
- 2.1 核心原理
- 2.2 举个栗子(不带冲突)
- 2.3 带冲突的three way merge
- 3 变基rebase
- 3.1 引入rebase
- 3.2 核心原理
- 4 冲突问题
- 4.1 产生冲突的原因
- 4.2 常见冲突场景
- 4.3 解决冲突
前言
合并操作在Git中属于最为核心的一个操作,包括三种合并方式:一种为fast forward ,需要满足有非常强的前提条件才能执行;一种为3 way merge方式,这种是我们工作中常见的;最后一种为变基rebase。另外,本篇文章也会深入讲解冲突如何产生,以及如何解决
1 Fast Forword 合并
1.1 核心原理
需求:将bugfix分支合并到master(切换到master然后执行git merge bugfix)
Fast Forword 合并: 将master分支指针向前快速移动到bugfix分支所指向的commit对象,在此合并方式下,不会产生冲突
前提条件: bugfix和master分支具有完全相同的提交历史(即bugfix提交历史中有master最新的提交)
1.2 举个栗子
合并前描述:
master分支指向C2代表的commit对象,而bugfix超前于master分支1次提交(这里可以超前多次),指向了C3所代表的commit对象。符合fast forward merge
执行命令
git checkout master
git merge bugfix
合并后描述:
master指针快速移动到bugfix指针所指向的commit对象C3
合并过程中发生的事情:
1、.git/ 目录下会新增一个文件 ORIG_HEAD文件,该文件为指向master上一次commit的指针,用于回滚,即若发现合并错了,那执行git reset ORIG_HEAD
即可完成回滚操作
2、不会产生新的commit、bolb、tree对象
1.3 经验之谈
在实际工作场景中,此合并方式基本不会遇到,除非代码仓库只有自己在维护。而我们通常遇到的情况都是下面要讲的3 way merge 或者rebase的情况,也即bugfix和master分支不具有完全相同的提交历史,产生了分叉
2 three way merge
2.1 核心原理
需求:将bugfix分支合并到master(切换到master然后执行git merge bugfix)
three way merge: Git 需要比较三个版本的代码,即两个分支的最新提交对象和它们的共同祖先提交对象。Git 使用一种叫做三方合并(three-way merge)的技术来自动合并这三个版本的代码。
合并过程:
1、找到两个分支的共同祖先提交对象,确定两个分支之间的修改范围,确定冲突的位置
2、比较两个分支的最新提交对象和共同祖先分支之间的差异,确定每个分支中的修改内容。
3、合并两个分支的修改。根据比较结果,Git 将两个分支的修改合并起来。如果两个分支对同一个文件的不同部分进行了修改,Git 将尝试自动合并这些修改。如果这些修改发生在同一个文件的同一个区域,Git 就会提示用户手动解决冲突。
2.2 举个栗子(不带冲突)
合并前描述:
A用户对master执行了合并,使得master指针从C2变为了C4;B用户对bugfix执行了commit操作,使得bugfix从C2变为了C3,此时,产生了分叉。我们的目标是要将bugfix合并到master上
执行命令
git checkout master
git merge bugfix
此时会跳转到一个vim界面,编辑本次merge包括了哪些信息,这个自己填写就可以
合并后描述:
产生一个新的commit对象C5,它的parent有两个,C3与C4,同时master指针指向C5,合并完成
2.3 带冲突的three way merge
合并前描述:
master和bugfix对同一文件的同一区域进行了修改,现在要将bugfix分支合并到master
执行命令
git checkout master
git merge bugfix
此时会显示如下冲突信息
此时也可以使用git status
来查看有哪些文件产生了冲突
然后可以使用git diff 冲突文件路径
来查看差异,最后可以手动解决(git add git commit即可)。
当然目前有很多IDE内置了很方便的冲突解决功能
合并后描述:
产生C4,parent是C2,C3,C4中的test.txt是你解决完冲突后的内容
3 变基rebase
git rebase命令适合有强迫症的人使用。
3.1 引入rebase
3 way merge方式在git历史线上会产生分叉,类似下面,红色代表dev,蓝色代表master
有些人就觉得,不行,必须得是直线才好看,也就是想在3 way merge的方式下还想达到fast forward的效果(fast forward在git 历史上是直线),所以产生了git rebase
3.2 核心原理
核心原理:将一个分支的修改“移动”到另一个分支上。
基本步骤:
git rebase根据会新增commit 对象。待补充
4 冲突问题
4.1 产生冲突的原因
核心原因:多个分支对同一个文件的同一部分进行了修改,并且这些修改是相互矛盾的,无法自动合并。
具体来说,当多个分支对同一个文件的同一部分进行了修改时,Git 会尝试自动合并这些修改,并将合并结果应用于最终合并结果中。但是,如果这些修改是相互矛盾的,例如一个分支将文件的某个部分删除了,而另一个分支对该部分进行了修改,则 Git 就无法自动合并这些修改,会提示合并冲突。
在这种情况下,开发者需要手动解决冲突,从而完成合并操作。手动解决冲突的过程中,开发者需要根据需要保留、修改或删除对应的代码行或代码段。解决冲突后,开发者需要将修改提交到 Git 仓库中。
4.2 常见冲突场景
1、git merge时(3 way merge)
2、git pull时
以下场景不会产生冲突:
场景一:
假设有两个分支,分别是 A 和 B,它们都对同一个文件 file.txt 进行了修改:分支 A 对 file.txt 进行了删除操作; 分支 B 对 file.txt 进行了修改操作。 这时候,如果要合并这两个分支,Git就会自动先将分支 B 对 file.txt 的修改操作合并到最终合并结果中,再将A 对 file.txt 的删除操作合并到最终合并结果中,而不会提示合并冲突
最终合并的结果是file文件被删除了
4.3 解决冲突