zoukankan      html  css  js  c++  java
  • rebase after merge

      git真是博大精深。

      想通了这一点,再遇到什么奇怪的现象都不奇怪了,查文档就是了。

      今天来谝一谝git使用中遇到的一个有趣的场景:本地有master,spike两个branch。因为spike的内容和master完全不想相关,所以在spike上工作了若干天都没理master,直到有一天觉得差不多了,就做了以下几件事情。

      git co master

      git merge spike

      git pull --rebase

      然后奇怪的事情就发生了,那么到底发生了什么奇怪的事情呢,我还是决定把问题稍微简化一下,然后再慢慢道来。因为大家知道git pull --rebase其实就等于git fetch + git rebase。只不过rebase的upstream是远程的一个分支而已。本着git之内,本地分支和远程分支皆平等的原则,上面的那个例子使用本地分支做演示也是等效的。先看下面的这个历史:

      我除了一个master分支,还有两个分支,名为br1和br2。然后来做个git co master + git merge br1,历史变成了这样:

      多了一个合并提交,不好看。然后我们再尝试把master rebase到br2上面。那么具体git会怎么做呢。说到这里我想暂停下,大概说下git rebase到底是怎么工作的。简单的说,git rebase接受最多三个参数:

      git rebase --onto newbase upstream branch。

      把这句话翻译成中文就是:从branch指定的那个分支的HEAD开始往前找提交,直到找到第一个和upstream分支共同的祖先,然后把前面找到的那些提交(不包含找到的那个共同的提交)依次的安放到newbase指定的那个branch的HEAD上。如果看完没感觉,那。。。看后面的例子吧。

      为什么说最多接受三个参数呢?因为它还可以接受如下两种参数形式:

      git rebase upstream branch // upstream即newbase

      git rebase upstream            // current branch即branch

      好,我们接着刚才那个例子看。如果这个时候,我做一个 git co master + git rebase br2,会怎样?  

      没错,这个就是结果,那么这个结果如何的出来的呢?请跟着我的节奏把刚才那个定义过一遍。首先我们把这个接受一个参数的命令补全成为接受三个参数的命令

      git rebase --onto br2 br2 master

      即首先从master开始往前找和br2的共同祖先提交,找到了两个:2和3。而2和3之后的那些被找到的提交就是5和6了,由于我们做rebase,那个合并提交就没有存在的必要了,所以接下来就要把5和6这两次提交放到br2的HEAD上面。br2的HEAD现在是4,所以master就变成了上图的那个样子。但是你们master和br2在那做rebase,不能影响人家br1吧。所以br1该是啥样子,还是啥样子,人家本来HEAD就在5上,现在还是保持在5上面。这样就造成了两个奇怪的现象:

      1,原来的那个合并提交不见了,原来从2提交分出去的那个两个分支现在都乖乖的顺次摞在br2上面了,分支不复存在了。

      2,由于提交5之前同时被master和br1这两个分支占着,当master移走了之后,就出现了5这次提交出现了两次,一个在master上面,一个在br1上。

      那么如果我再做一次git rebase br1 master,会怎样呢?让我们再顺一遍刚才的那个定义。从master往前找和br1的共同祖先提交之后的那些提交,即4,5,6。然后再把4,5,6顺次放到br1的HEAD,即5上。就变成了5,4,5,6。

      嗯。。。看起来不是很对,master上的5这次提交和br1上的5这次提交虽然事实上是两次不同的提交(提交号不一样),但其内容是一模一样的(也就是那些insertion和deletion)。这时候git就比较聪明了,看到两次一样的提交,就丢掉了后面那个。事实上的结果变成了:5,4,6。即:

      最后需要提醒一下的是,前面提到的那些1,2,3,4,5,6都是提交的message而已,message相同是因为提交的内容相同,也就是diff相同,但是是不同的提交,因为提交号不一样。在git的历史里面不可能出现两个提交号一模一样的提交的。

      大概就说到这里,总结一下就是,git非常灵活,灵活到经常可能被误用。所以当出现上面提到的那个“奇怪的现象”的时候,就要考虑下是不是自己用的不大对头喽。

  • 相关阅读:
    [J2ME Q&A]MMAPI的Cannot parse this type of AMR异常之讨论
    FM91.5的EasyMorning节目爱听吗?
    [EntLibFAQ]“不允许所请求的注册表访问权”的解释[0508Update]
    亮出你的组合竞争力的王牌
    隔离,隔离,再隔离!
    zuma三阶段论和技术道路[一]
    分享下我们部门内部知识点培训教程[SIP/J2ME/Setup/LoadRunner/Domino][0706Up]
    [Remoting FAQ]Loading a Remoting Host On IIS得到BadImageFormatException
    通过讲课来建立自己的知识系统
    j2medev“用户界面和多媒体”版面问题整理[0407更新]
  • 原文地址:https://www.cnblogs.com/cuiliqiang/p/2555409.html
Copyright © 2011-2022 走看看