上篇博客聊了《Git知识总览(三) 分支的创建、删除、切换、合并以及冲突解决》,本篇博客我们主要来看一下 rebase 变基相关的操作。rebase 操作和 merge 操作最终都可以达到合并代码的效果,不过其对分支的影响不同。上篇博客中我们聊到了 merge操作。简单的说merge操作就是将两个commit进行合并,然后在这两个分支合并的基础上创建一个新的commit。而变基操作简单的说是改变提交的父类,在改变父类时进行合并操作。合并就可能产生冲突,所以rebase时也会产生冲突,下方会介绍到。

聊完rebase,下方还聊如何进行cherry-pick。cherry-pick的本质其实也是合并,只不过是可以将任意分支,任意提交合并到相关分支。当然只要是合并操作,都有可能产生冲突,下方会给出cherry-pick操作的基本使用以及如何解决cherry-pick时产生的冲突。

一、merge 与 rebase 的简单对比

下方是我们做操作之前的分支状态,共有 bugFix、side 、another 三个分支。现在我们要做的是分别使用 merge 和 rebase 将分支 side 中的内容合并到master分支。

  

首先我们先来看一下 merge 操作。上篇博客中已经详细的聊了merge的相关操作,再次就不做过多的展示了,下方只做了简单的展示。

  • 首先切换到master分支

  • 然后在master分支上执行 git merge side 操作,将side分支上的内容合并到master分支上。

  • 最后如果需要的话,在将side分支的指针指向master分支即可。

  

然后我们再看一下 rebase 下的相关操作。

  • 首先切换到 side 分支。

  • 然后在 side 分支上执行 git rebase master 操作,将其变基到master分支上。

  

二、rebase的基本操作

首先我们来看一下在git分支管理中如何使用rebase, 以及rebase的后会起什么作用。下方会根据一系列的示例来看一下rebase操作的实际效果。首先我们先来看一下做rebase操作之前的分支状态,如下所示。目前除了master主分支外,还有其他三个分支,分别为bugfix01、bugfix02、bugfix03。

现在要做的事情是在 bugfix01 的分支上执行rebase操作,将其变基到master分支上。

  

下方是在 bugfix01分支上执行的 git rebase master 将bugfix01分支变基到master分支上,下方是变基后的分支状态。从下方的分支中不难看出,之前在 master 分支后方的 bugfix01现在跑到了master分支的后方,并且 bigfix01 分支上的两个提交(3cc582b、f47d2ac)不见了。取而代之的是基于master分支的两个新的提交(d6d82d8、14bc685)。这两个新的提交不但包含了3cc582b、f47d2ac这两个旧的提交的内容,而且还包含了master分支当前指向的分支(b79aa11)提交上的内容。

  

上面的表达也许有点抽象,下面我们可以话一张图来表示上述的关系。根据上面的分支关系,简单的画了一下上面的 rebase 操作所对应的关系图。rebase 操作完后,下方画红框的分支就被废弃掉了。然后bugfix01会指向rebase后的commit上。

  

接着上面的操作,可以切换到master分支,然后执行 git merge bugfix01 命令,将master分支快速移动到bugfix01分支上所指向的内容上。下方就是快速移动后的结果。经过这步后,就完成了一次rebase操作。从rebase操作的结果来看,其对 git 的分支进行了整理,换句话说,rebase操作可以将其他分支上的内容合并到主分支上,合并后之前的分支的指针的指向也会随之变化,变化后之前的提交就会被抛弃掉。

  

变基是存在一定风险的,在 ProGit上有一句话:Do not rebase commits that exist outside your repository. 大概意思就是说:不要在你的仓库在其他地方存在副本的情况下,对分支执行变基。也就是说,你从远程Clone下来代码,然后对之前的操作进行了rebase, 并且强推到远端。如果别人也clone的相关仓库,在其分支上做了相关操作。在push之前执行pull时,因为之前的分支被你rebase了,也就是有了新的提交,在pull时,就会进行merge操作。这样一来,分支就会更加复杂。如果出现上述问题 就使用rebase 来解决问题,即使用 git pull --rebase 来执行。

这一块具体的东西还是参考ProGit上的内容来的比较直观,在此就不做过多赘述了。

三、rebase的冲突解决

为了看rebase冲突的解决方式,我们故意的制造了下方的冲突,然后去执行rebase操作。从下方的操作中不难看出,在rebase的过程中产生了冲突,需要我们去解决。解决冲突后将相关问题件进行commit, 然后使用 git rebase --continue 操作来继续rebase。

因为rebase时会合并多个提交,在多个提交合并时会产生多个冲突,所有在一个冲突解决并提交后,进行git rebase --continue继续合并接下来的点。继续后仍然有可能产生冲突,产生冲突即解决冲突,直到rebase结束为止。

四、cherry-pick的基本操作

接下来我们来看一下git中比较实用的一个命令:cherry-pick。这个命令的名字是比较形象的,cherry-pick即“摘樱桃”,使用该命令可以将任意的commit通过其commit号将其合并到你想要的分支上。接下来我们就来看一个例子。

下方就演示了cherry-pick命令的使用方法。在 master 分支上,执行 git cherry-pick <一些commit的哈希值> 然后将这些提交合并到master分支上。这些分支会根据cherry-pick的顺序进行merge,每次merge都会形成一个新的提交。与rebase命令不同,虽然会产生一个新的提交,而之前的提交是不变的。具体如下所示:

  

接下来我们来看一下具体在终端上cherry-pick的操作命令。下方是目前分支的状态,并且处于master分支上。现在我们要做的事情是将 d98ff43  这个commit 拿到master上。

  

下方就是我们执行cherry-pick的命令,如下所示。下方执行cherry-pick时是非常顺利的,没有产生冲突。当提交进行合并时会产生冲突,就不是这个样子了,稍后会演示到。

  

下方就是顺利的cherry-pick后的样子。

  

五、cherry-pick的冲突解决

在cherry-pick时遇到冲突是避免的,下方特地搞了一个cherry-pick冲突的例子。为了更进一步的了解冲突的解决方式,下方cherry-pick了多个提交,而且这多个提交在merge时都会有冲突。下方我们会对这些冲突进行解决。

  • 首先我们在master分支上通过 git cherry-pick <一系列提交的哈希值>来将 4f8e019、dbe9e8a、5c52520这三个提交摘到master分支上。

  • 然后我们会先看到在cherry-pick 4f8e019 这个提交时产生了冲突,报了一个Error:提升不能将cherry-pick命令应用于4f8e019。并且下方给了一系列的提示(解决此错误可以通过正确的方式解决冲突,然后通过git add 或者 git rm将更改的文件进行追踪,最后可以使用 git commit进行提交)

  • 解决一个冲突并commit后,使用 git cherry-pick --continue可以进一步的进行下一个提交的cherry-pick。下方再次执行git cherry-pick --continue时,又出现了冲突,此刻我们还是按照上述的步骤对冲突进行解决,解决完毕后接着git cherry-pick --continue。直到所有的commit被合并完毕即可。具体操作步骤如下所示:

  

下方是上述操作的最终结果,cherry-pick了三个commit,冲突了三次,解决了三次。如下所示:

  

下篇博客会继续聊Git的相关的内容。

Git知识总览(四) git分支管理之rebase 以及 cherry-pick相关操作的更多相关文章

  1. Git知识总览(二) git常用命令概览

    上篇博客我们从 git clone 和 git status 两个命令开始,引出了一系列的git操作命令, 请参见:<Git知识总览(一) 从 git clone 和 git status 谈起 ...

  2. Git知识总览(五) Git中的merge、rebase、cherry-pick以及交互式rebase

    上篇博客聊了<git分支管理之rebase 以及 cherry-pick相关操作>本篇博客我们就以Learning Git中的关卡进行展开.下方列举了LearningGit中的 merge ...

  3. Git学习(四)——分支管理

    一.创建与合并分支 1.创建分支 一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点.每次提交 ,mast ...

  4. Git知识总览(六) Git分支中的远程操作实践

    前几篇博客陆陆续续的讲了好多关于Git操作的内容,本篇博客仍然也不例外,不过本篇博客的主题是关于git的远程操作的.依照之前博客的风格,我们依然依托于LearningGitBranch中的相关内容来探 ...

  5. Git之(四)分支管理

    当我们初始化Git仓库的时候,Git会默认创建一个名为master的主分支.在实际工作中,主分支要求是一个稳定.健壮.安全的主线,一般不允许在主分支上直接进行开发,而是拉取一个新的分支,开发.测试完成 ...

  6. Git知识总览(三) 分支的创建、删除、切换、合并以及冲突解决

    前两篇博客集中的聊了git的一些常用命令,具体请参见<Git知识总览(一) 从 git clone 和 git status 谈起>.<Git知识总览(二) git常用命令概览> ...

  7. Git 学习(六)分支管理

    Git 学习(六)分支管理 几乎每一种版本控制系统都支持分支.使用分支意味着你可以从开发主线上分离开来,然后不影响主线的同时继续工作.在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录 ...

  8. git学习(5)分支管理(续)

    git学习(5)分支管理(续) 1.解决冲突 冲突的产生 如我们在新建分支和原来master分支上对同一文件做了修改并提交,在合并分支的时候就会遇到冲突 比如我新建了分支myBranch,在这个分支上 ...

  9. Eclipse集成Git做团队开发:分支管理

    在日常开发工作中,我们通常使用版本控制软件管理团队的源代码,常用的SVN.Git.与SVN相比,Git有分支的概念,可以从主分支创建开发分支,在开发分支测试没有问题之后,再合并到主分支上去,从而避免了 ...

随机推荐

  1. video 在微信中,安卓全屏和ios上如何内联播放?H5同层播放器相关接入规范

    今天在做一个分享页面的时候需要播放视屏用了video,然后各种坑开始了: <video src="http://xxx.mp4 " id="myVideo" ...

  2. hexo next主题为博客添加分享功能

    title: hexo next主题为博客添加分享功能 date: 2018-01-06 20:20:02 tags: [hexo博客, 博客配置] categories: hexo next主题配置 ...

  3. 聊聊ThreadLocal原理以及使用场景-JAVA 8源码

    相信很多人知道ThreadLocal是针对每个线程的,但是其中的原理相信大家不是很清楚,那咱们就一块看一下源码. 首先,我们先看看它的set方法.非常简单,从当前Thread中获取map.那么这个ge ...

  4. 【读书笔记】【深入理解ES6】#2-字符串和正则表达式

    更好的Unicode支持 在ES6出现以前,JS字符串一直基于16位字符编码(UTF-16)进行构建. 每16位的序列是一个编码单元(code unit),代表一个字符. length.charAt( ...

  5. Python编程笔记 - 列表

    这篇文章开始介绍Python中的容器.Python容器包括列表.元组.集合与字典.这些数据结构中都涉及到很多的方法,这里对比较常用的一些方法进行介绍,不用每个方法都记住,熟悉常用的即可. 首先,我们先 ...

  6. js网页返回顶部和楼层跳跃的实现原理

    这是简单的效果图. (实现楼层间的跳跃,主要依靠的是 window.scrollTo(x,y)方法 ,将浏览器的可见区域移动到指定的x,y坐标上.)   说楼层跳跃前,先温习下,一般网页在高度较大时, ...

  7. 简单的基于hash和hashchange的前端路由

    hash定义 hash这个玩意是地址栏上#及后面部分,代表网页中的一个位置,#后面部分为位置标识符.页面打开后,会自动滚动到指定位置处. 位置标识符 ,一是使用锚点,比如<a name=&quo ...

  8. HDU 2602 Bone Collector(01背包裸题)

    Bone Collector Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  9. [ZOJ3213] Beautiful Meadow

    插头DP...网格图,有障碍,格子上有权值,求总权值最大的简单路径. 因为路径的起始点不确定..所以多开一维表示当前已经有多少个独立插头.. 只要不合并相同的联通块,并且已经用了2个独立插头,那就是一 ...

  10. Git服务搭建及github使用教程

    .pos { position: fixed; top: 35%; left: 90% } .pos a { border: 2px solid white; background: #99CCFF; ...