zoukankan      html  css  js  c++  java
  • Git知识总览(四) git分支管理之rebase 以及 cherry-pick相关操作

     

    上篇博客聊了《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的相关的内容。

    作者:青玉伏案 
    出处:http://www.cnblogs.com/ludashi/ 
    本文版权归作者和共博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 
    如果文中有什么错误,欢迎指出。以免更多的人被误导。

  • 相关阅读:
    Poj 2017 Speed Limit(水题)
    Poj 1316 Self Numbers(水题)
    Poj 1017 Packets(贪心策略)
    Poj 1017 Packets(贪心策略)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    Poj 2662,2909 Goldbach's Conjecture (素数判定)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2388 Who's in the Middle(快速排序求中位数)
    poj 2000 Gold Coins(水题)
    poj 2000 Gold Coins(水题)
  • 原文地址:https://www.cnblogs.com/brady-wang/p/10604601.html
Copyright © 2011-2022 走看看