《Git/Gitlab进阶》九:测试merge和rebase分支
本章主要测试讲解
-
git merge
和git rebase
指令的用法和进行分支合并,并做简单比较分析。
测试过程内容较多,每个步骤都逐一截图以便真实说明,也有列示用法。若不感兴趣,可直接查看总结部分。
测试过程
前置说明
关于无论是使用 merge 还是 rebase 进行合并,出现冲突的原因都是在不同的分支修改了同一处的代码,合并时版控工具 git 不知道保留哪一份的修改,从而导致冲突,需要合并人员去判断并解决。
使用 merge 和 rebase 合并的做法

大概流程:
测试 git merge 和 git rebase 的合并及解决冲突效果:
- 1 准备测试项目及分支记录
- 创建 master、dev1、dev2 三个分支
- 除了 master 创建 dev1 和 dev2 的初始提交外,3 个分支各自有两个不同的提交记录
- 时间顺序为:
master 新建空文件,再初始提交 –>
创建 dev2 –> dev2 commit 第一次文件修改 –> dev2 commit 第二次文件修改 –>
切回 master 创建 dev1 –> dev1 commit 第一次文件修改 –> dev1 commit 第二次文件修改 –>
切回 master –> master commit 第一次文件修改 –> master commit 第二次文件修改 –>
进行使用 git merge/git merge 合并测试……
- 时间顺序为:
- 2 使用 git merge 进行合并
- 3 使用 git rebase 进行合并
- 4 对比两者合并的历史记录,分析优缺点和使用场景
测试步骤
准备测试项目及分支记录
相关命令请看截图
准备测试项目 test-conflict,新建一个 test1.txt 文件(后续新建的文件,最好都改成 UTF-8,windows 下默认是 ANSI,操作可能会产生乱码),内容为空,并 master 分支初始提交。

以 master 分支创建 dev2 分支

dev2 以 master 分支为基准,所以 test1.txt 还是为空的,两次修改 test1.txt

此时 dev2 的历史记录为

切换到 master 分支,并创建分支 dev1 并修改文件 test1.txt,然后分别提交

然后再修改一次,然后第二次提交

此时 dev1 的日志记录如下

此时切回到 master 分支,自行也修改并提交两次 test1.txt 的修改

此时 master 分支的记录为

直至,准备工作完整,我们打包一份,保留 2 个一模一样的项目,一个测试 git merge,一个测试 git rebase
使用 git merge 进行合并测试
步骤说明:
- 切换到 master 分支,先合并 dev1 到 master,再合并 dev2 到 master
- 因为 dev1、dev2 和 master 原本分支都有修改到 test1.txt 的同一行,所以会出现多次的合并冲突,需要手动解决
- 合并完成之后,查看 git merge 的 master 的日志
创建时现有 dev2 的提交,但是合并时,先合并 dev1
合并 dev1 到 master,出现冲突

手动解决冲突并提交

再合并 dev2 到 master,依然报冲突

手动解决并提交

至此,使用 git merge 已把 dev1 和 dev2 合并到 master 分支,查看 master 分支的日志。

至此使用 git merge 合并和解决冲突测试完成。
使用 git rebase 合并冲突
使用之前的备份项目测试 git rebase
步骤说明:
- 切到 dev1 分支,rebase dev1 到 master,解决合并冲突
- 切回 master 分支(此时 master 的日志还没变),进行一次快速合并到 dev1(现在就变了)
- 切到 dev2 分支,rebase dev2 到 master,解决合并冲突
- 切回 master 分支,进行一次快速合并到 dev2
- 合并完成之后,查看 git rebase 的 master 的日志
切回 dev1 分支,rebase dev1 到 master,会产生冲突。

修改成以下内容之后,再执行 git add .(没有执行 commit),然后继续进行 rebase

继续进行 rebase,则弹出第二次冲突提示

从文本来看,因为有两行是冲突的,第一次解决冲突是 master 中于 dev1 第一次提交有冲突的内容,现在报的是与 dev1 第二次提交有冲突的内容,同样手动解决,然后继续,可见 rebase 完成。

至此,使用 rebase,已经把 dev1 上的两次提交的修改变基到了 master 分支的提交修改上。
现在切回 master 分支(当然,此时 master 的日志还没变),进行一次快速合并到 dev1(现在就变了)

同样的,再合并 dev2,同样解决两次冲突,
第一次冲突

解决如下

第二次冲突

解决如下:

合并完成

同样,现在切回 master 分支,进行一次快速合并到 dev2,查看日志

git merge 和 git rebase 的结果对比
使用 git rebase 后,3 个分支的历史记录如下

git merge 历史记录如下

总结
git merge 和 git rebase 进行合并的区别:
- 历史记录不同
- git merge 保留了各个分支各自的提交记录,如果有解决冲突,会单独创建一次 commit 记录冲突的解决,历史记录完整。
- git rebase 只有一根线的分支记录历史,手动解决的冲突不会创建保留记录,历史记录清晰简单
- 操作步骤不同
- git merge 操作简单,
- git rebase 操作步骤繁琐。
- 影响范围不同
- git merge 操作未对 dev1 和 dev2 的项目内容(或提交记录)进行异动,不会影响后续人员对此两个分支进行接续作业。
- git rebase 操作已经对 dev1 和 dev2 分支进行了异动,如果有后续分支使用了这两个分支,可能会导致提交历史记录的混乱和其它异常情况。
建议:
只对尚未推送或分享给别人的本地修改执行变基操作清理历史,不要对已推送至别处的提交执行变基操作。

个人建议
对于合并,如果始终不清楚 merge 和 rebase 的区别,推荐使用 merge。
merge 的一大优点是简单,不会对其它分支造成影响。
唯一可能的不足就是会有比较多(不清晰)的提交记录,这一点可以使用 git rebase -i <commit id="" style="box-sizing: border-box;">,进入 interactive 模式(后续文章有介绍),对历史记录进行修改</commit>
新手提醒:如果需要合并的分支还有未提交的修改,是没有办法合并的。

Bonus:修改分支的名字
假如从 master 分支创建了一个 feature-branch 分支,结果写成了 future-brunch

直接使用git branch -m
参数修改即可
git branch -m future-brunch feature-branch
