Git使用 从入门到入土 收藏吃灰系列 (十二) git merge 与 git rebase

126 阅读7分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

本节内容速览

  • git merge的应用场景
  • git rebase的应用场景
  • git mergegit rebase有什么区别

一、前言

讲讲小张的感受:我没有接触过Git,所以看了很多视频,对于入门使用确实只要知道git clone,git add,git commit,git push,git merge ,确实也就足够了。但是我很好奇背后的原理,为什么要用git add到暂存区而不是直接git commit?很多指令之间为什么要按一定的顺序执行?所以这个系列我以初学的时候,小白的角度从安装到工作原理(有的是我自己的见解,如果感觉不对,欢迎指正),再到实际应用!另外,推荐看一遍第三个参考视频,然后看一下第四个参考视频,对工作原理的讲解和实际应用确实不错!

二、git merge 合并分支的变更

这里合并的是分支的变更而不是分支的内容。

git merge <branchName>

通过实际给大家模拟一下

eg:主管开发了一个项目,功能有A。员工小张、小王分别新建一个分支。小张开发了新功能B,小王开发了新功能C。之后主管将两条分支合并到master分支中。

graph LR;
    master-->A;
graph LR;
   zhang-->A;
    A-->B;
graph LR;
    wang-->A;
    A-->C;

合并

graph LR;
    master-->A;
    A-->B;
    B-->C;

上代码模拟

每一次add .,本地仓库都要做变化,随便加、改一个文件内容就行。这里我修改A.txt的内容

  1. 在主分支创建A.txt,内容为"主管"。之后提交到本地仓库
主管

img-xsDCzatF-1644894324164

  1. 创建分支git branch zhang,git branch wang

img-Kr1LxnlJ-1644894324165

  1. git checkout zhang切换分支zhang。修改A.txt的内容,并提交本地仓库
主管

小张

image-20220119195219199

  1. git checkout wang切换分支wang。修改A.txt的内容,并提交本地仓库
主管

小王提交

image-20220119195254413

  1. git checkout master切换分支master。合并zhang分支到master

img-5YssrUdm-1644894324167

现在我们的文本变成了这样

img-IrSg5TvK-1644894324170

  1. 合并wang分支到master

img-RECIHQte-1644894324171

如图,这里显示**“自动合并失败;修复冲突,然后提交结果”**。因为现在的A.txt是master和zhang两个分支合并的结果

打开A.txt

img-JNP2EAdz-1644895901906

手动修改为

主管

小张

小王提交

然后添加到本地仓库即可

img-oOI6ejub-1644895935696

查看日志,这里记录了所有的提交记录

img-55ZUBci9-1644894324174 使用git log -p可以查看日志,概览如图

graph LR;
   主管提交-->小张提交;
    小张提交-->小王提交;
    小王提交-->保留双方变更;
    小张提交-->保留双方变更;

Q:为什么最后分支图会分叉?

A:新分支都是继承master分支"主管提交"这条记录。zhang分支的记录前进到"小张提交",而wang分支只是在"主管提交"这条记录的基础上修改,所以也是在"主管提交"之后。zhang分支合并时没有冲突但合并wang分支时本应该链接"主管提交"之后,但是"主管提交"之后现在链接"小张提交",所以会有分叉

这种分叉可以暂且叫做 “三方合并” ,将“主管提交”,“小张提交”,“小王提交”,三者合并

graph LR;
    主管提交-->小张提交;
     主管提交-->小王提交

日志可以完整到看到这个开发的过程,但是过多使用merge,会产生很多很多的分叉,分叉之间又相互联系。四五个人不明显,但当十多个人共用一个仓库,整个开发流程就会很乱,进阶git可以学习一下后面讲的rebase,可以将整个开发流程整合为一条线

eg:merge太多

image-20220122114555692

三、git rebase 变基

前面学习了git merge,作用是为了合并分支,了解到git merge会使日志变得混乱。git rebase也是合并分支的作用,但所谓"变基",就是改变他们的"基",将日志整理为一条直线

假定有一个master分支,在这个分支上有两次commit。之后切出了分支bc,此时bc和master的commit完全一致。之后bc有了第三次、第四次commit,master也有了一次提交。

img-l6CUHjXl-1644894324175

为了区分commit按时间顺序编号。现在bc以master的前两次commit为基础发展的。如果想要以最新的master版本为base提交commit。也就是说让bc变成1、2、5、3、4一条线,而不是merge那样有分叉,这里就需要用rebase

img-0auqxaMl-1644894324175

rebase原理是枚举变更的commit,依次变基。先拿出3号commit,然后以125为基础添加3号commit,再拿出4号commit,以1253为基础添加4号commit。直至所有新增commit完成变基。所以rebase就是重新排列base。base就是指commit。

实战模拟

先在master完成两次commit。在bc分支完成两次commit。切回master完成一次commit

1.git log查看master和bc分支的提交记录

img-pyXrxPfJ-1644894324176

2.在bc分支中执行git rebase命令,出现冲突手动解决即可。

image-20220119212632284

3.处理完后add到暂存区,继续下一个commit结点的rebase。

git rebase --continue

重复2、3后如图

在这里插入图片描述

第一种使用情况

# 变基	整合多条记录到一条
git rebase -i <哈希值>
git rebase -i HEAD~数字 	#从当前记录到前x个记录合并

在开发一个项目时,有四次提交记录,第四次开发完,老板只想看到最初的和最终的日志文件。可以使用git rebase简化记录。

1.使用git log查看日志

img-839StQlI-1644894324178

2.合并三条记录

# 执行任意一个
git rebase -i 80fe8d5cea94a687064a740e6e3f3c91a28032d9
git rebase -i HEAD~3 	#从当前记录到前x个记录合并

下面是提示命令的,自己翻译一下很好懂。按i进入vim编辑,这里执行S。然后按Esc输入:wq(表示保存并退出)

img-HpqPXFqu-1644894324178

删掉前几次提交的信息输入新的commit。然后按Esc输入:wq

mg-WUac14vt-1644894324179

合并成功,之后可以git log一下看一下变化。

img-gUIwkUCV-1644896769688

==注意:== 不要对已经push过远程的记录进行git rebase -i HEAD有可能会反而更乱

第二种使用情况

接着第一种情况的命令窗口继续操作

1.新切一个dev分支,并提交一次记录

img-XfGk2YEq-1644894324180 2.切回master分支,新建一个文本,提交一次记录 img-HVAKYYuC-1644894324180 3.用git merge合并devmaster。(如果十多个人的团队开发项目,一直使用merge,开发记录就会很凌乱) img-bRMmWu9K-1644896824213 4.切回dev,合并master dev img-zg3iKyte-1644896831854 5.在dev中提交一次记录 img-Hi8QtayE-164489432418

6.切回master提交一次记录 在这里插入图片描述 7.切回到dev分支,git rebase mg-i0TnBSzL-1644894379392 8.因为最终代码要放回master主分支,所以切回master,执行git merge image-20220122124034372 这样提交记录就是一条线而不是分叉,使提交记录显示的非常简洁。如果有点凌乱可以理解为,在dev分支中git rebase master是将master中的记录并过来成==一条线而不是分叉==,之后再回到master,git merge dev,这样就不会产生分叉。不在master中直接git rebase是因为master是稳定的主分支,避免合并产生其它冲突使master中的代码损坏

下节介绍

  • git stash 存储到堆栈
  • git tag 标签
  • git check-pick 挑选合并
  • git diff 比较信息差异