记一次"诡异"的git merge错误

前言

今天照常开发,在日常部署测试的时候进行git merge 竟然出现了"代码丢失"的情况,相当诡异,特此记录。

问题由来

首先介绍下公司的日常发布测试的策略,公司使用git进行代码管理。如果某应用同时有多人开发,采用的方式是A会基于master新建feature_a分支,B基于master新建feature_b分支,然后在日常测试部署的时候通常会新建一个新的tag分支,如tag/20160711_test_xxxx,然后将要测试部署的分支feature_a和feature_b合并到tag分支上去,然后使用tag分支部署并且测试。这样做是完全没有问题的,但是诡异的事情发生了,今天这么操作的时候合并出的tag分支丢了一行import,mavan编译一直出错

问题描述与分析

最开始碰到这个问题的时候我一直以为是发布构建系统的问题(公司内部系统),后来又怀疑是我在解决merge冲突的时候手贱删除了这行,重新merge还是出现这个问题。后来由于还得开发其他功能,想着要不先让feature_b分支先单独发布测试好了。一直到下午手里的事情忙完了准备搞定这个问题,发现同事feature_b分支还是没有测试好,想着不能等他了,开始着手解决这个问题。

问题描述如下,feature_a和feature_b同时修改了某个文件xx.java,feature_a上xx.java大概类似于:

package xxx.xx
import com.xx.xx.A
import com.xx.xx.Common

class xx {
  public void commonMethod(Common common){
  }

  public void aSpecMethod(A a){
  }
}

feature_b上的xx.java大概类似于:

package xxx.xx
import com.xx.xx.B
import com.xx.xx.Common

class xx {
  public void commonMethod(Common common){
  }

  public void bSpecMethod(B b){
  }
}

按理说合并出来的代码应该类似于:

package xxx.xx
import com.xx.xx.A
import com.xx.xx.B
import com.xx.xx.Common

class xx {
  public void commonMethod(Common common){
  }

  public void aSpecMethod(A a){
  }

  public void bSpecMethod(B b){
  }

}

但是最终合并出来的代码却是类似于这样:

package xxx.xx
import com.xx.xx.B
import com.xx.xx.Common

class xx {
  public void commonMethod(Common common){
  }

  public void aSpecMethod(A a){
  }

  public void bSpecMethod(B b){
  }

}

筒子们发现问题了吗,NMmerge之后丢了import com.xx.xx.A这样,maven编译一直报解析不了A的错误,A都没引进来,能解析就怪了...

我也是年轻呀,开始的一个小时一直纠结在是不是这个发布系统的问题(哈哈,对不起,让你背锅了),后来开始仔细研究git merge的原理,期间看到了How-does-Git-merge-work这篇文章讲得比较通透。git merge的原理简单来说就是x+y-w的过程,其中w是x+y的merge base(也就是最近公共祖先),也即是说把y-w(y分支对w分支的改动)patch到x分支上,或者说是把x-w(x分支对w分支的改动)patch到y分支上,具体的做法就是:

merge过程

在知道原理之后就开始查看feature_b和feature_a分支分别对于xx.java文件的改动,发现feature_b(同事分支)将import com.xx.xx.A这句删掉了(看到这我就应该反应过来的,但是我还是太连清...),我当时想你删了就删了呗,我在feature_a分支引用进来了呀,最后合并肯定还是存在的嘛(我承认自己没仔细想),我接着checkout 到feature_a看了下,有import com.xx.xx.A这句呀,最后合并的时候肯定应该有的呀,git merge肯定不能因为某些分支删了这行就不新增其他分支的代码,心中一千匹草泥马在奔腾呀!!!!

但是...重要的是但是,我知道git merge首先会找他们的merge base,会基于这个合并,在该场景里应该是master(feature_a和feature_b都是基于master新建的),我就checkout到了master上查看了下,发现master上赫然存在import com.xx.xx.A这行(当时xx.java没有并没有引用到A.java类,这个import是多余的),我瞬间反应过来问题了!!

问题解决-真相大白

问题就在于x+y-w时和w是强相关的,而在这个案例里面,w(也就是master)的代码为:

package xxx.xx
import com.xx.xx.A
import com.xx.xx.Common

class xx {
  public void commonMethod(Common common){
  }

master中虽然没有引用A,但是却把A引进来了(应该是某次删除代码的时候忘了把Import删掉了)

先分析下xx.java的合并过程吧
x:代表feature_a
w:master
y:代表feature_b
合并过程为x+(y-w)
y-w在这个过程中表现
增加

-import com.xx.xx.A
+import com.xx.xx.B
+public void bSpecMethod(B b){
+}

x为

package xxx.xx
import com.xx.xx.A
import com.xx.xx.Common

class xx {
  public void commonMethod(Common common){
  }

  public void aSpecMethod(A a){
  }
}

合并出来的代码应该为

package xxx.xx
import com.xx.xx.B
import com.xx.xx.Common

class xx {
  public void commonMethod(Common common){
  }

  public void aSpecMethod(A a){
  }


public void bSpecMethod(B b){
}

}

哈哈,import com.xx.xx.A就这么丢了,而且还就应该丢,丢才是正确的!

筒子们,看出来问题了吗,问题就在于同事B看到xx.java中A并没有被引用的时候把A 的import干掉了,而我在xx.java中加入的方法刚好用到了A(我以为A是我import进去的,没想到竟然master上竟然存在),造成结果就是git 记住的改动是feature_b把A的import干掉了,feature_a对这个import没有修改,结果就是...

知道了原因,解决就很简单了,故意将Import A挪个位置并Push让git意识到change,这样下次merge的时候git既会知道feature_b的改动也会知道feature_a的改动会触发一次merge conflict,然后手动解决就好了

警示

在对类进行修改删除了某些方法时,一定要将无用的import清理掉,保持import区的干净!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容