决定开这个无限篇数,无限长系列是因为最近遇到了一个大坑(关于git的merge情况)。有感于这是我工作以来遇到的第一个大坑(显然不是最后一个),遂决定开这个系列的博客来记录以后遇到的所有坑,记录出坑方法,这样以后就不会踩同样的坑了,秉持的理念就是:再智障的问题不会也要问出来,再难的问题,再无可避免的错误也不犯第二次。尽量做到吧。计划博客结构如下:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="MaoLin Tian‘ s blog" xmlns="遇坑记实系列" targetNamespace="遇坑记实系列" elementFormDefault="qualified">
<xs:element name="遇坑记实">
<xs:complexType>
<xs:sequence>
<xs:element name="入坑" type="xs:string"/>
<xs:complexType>
<xs:sequence>
<xs:element name="入坑场景" type="xs:string"/>
<xs:element name="入坑原因" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="出坑" type="xs:string"/>
<xs:complexType>
<xs:sequence>
<xs:element name="出坑方式" type="xs:string"/>
<xs:element name="经验教训" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="避坑" type="xs:string"/>
<xs:complexType>
<xs:sequence>
<xs:element name="总结问题" type="xs:string"/>
<xs:element name="最佳实践" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
##入坑
我们都知道dev是用来开发的分支,master是用来上线的分支。一般流程是在dev上开发新特性,开发完成后合并到dev上,然后发布release版本,在release版本上交由测试人员测试没问题之后,再发布到master(同时上线对应的配置文件,脚本文件)。
###入坑场景
我实现的场景如下:这里我开发了新特性要往线上发布时的流程是:
- 从dev拉取分支为dev_maolin
- 开发完成后将代码合并到dev并拉取最新dev代码。换句话说就是保持和dev内容相同
- 将新特性代码与master合并并且合并master的代码。
这个流程可以说是极度混乱的四不像。
- 它不是标准的新特性发布流程,首先在第2步合并时完全没必要用dev_maolin去merge dev。 其次,标准新特性发布流程这里缺少release版本,没有测试环节。最后第3步合并时完全没必要用dev_maolin去merge master(会引入大量不想上线的别人写的特性)。
- 它不是标准的hotfix流程,因为hotfix是从master拉取出来的分支,同样也没有必要和master以及dev双向merge。
###入坑原因
这里为什么不能上线的最主要原因就是:我从dev里拉取出来分支去开发新特性,如果是等待发版和别人开发的功能一起上线,那问题不大,就算是release版本也是大家一起发嘛。问题就是,大家开发的特性还需要测试去发版,不急着上线,而我的代码今晚就要上线,但如果强行上线,别人的更改(未经测试)被引到线上,会导致线上出问题。所以应该把我的新特性确认为一个hotfix去看待。
##出坑
首先分析问题出在两个地方:
-
从dev拉取分支时间节点前就有很多别人开发的特性。
-
开发完新特性后merge dev时,又引入了很多dev拉取分支后别人在dev上开发的新特性。
###出坑方式
在遇到上述问题的时候导致的局面就是,首先dev_maolin和dev分支完全同步,接着dev_maolin分支又合并了master的代码,让master本地和并了dev_maolin的代码。立刻想到的处理方式有以下步骤: -
首先按照hotfix来看待自己的急需上线的功能,将本地master还原为merge dev_maolin前,确保本地master没被污染,然后从本地master拉取hotfix_master分支,准备接受自己的新特性代码。
-
将dev_maolin还原为merge dev节点之前,这样在开发新特性过程中别人开发的新特性就不会污染到dev_maolin分支,**但这样有个问题就是,从dev分支节点拉出dev_maolin之前别人开发的新特性无可避免,**所以这一步不奏效。
最后采取的方式是,上边两步骤都执行,然后将dev_maolin里所有代码拷贝到桌面,切换倒hotfix_master分支,将hotfix_master里所有代码拷贝到桌面,使用beyondCompare工具,依据记忆将自己的更改从dev_maolin覆盖到hotfix_master,然后再将hotfix_master合并到master。这样做有很大的问题,但实属无奈之举。
###经验教训
一定要准确定位自己的功能。到底要干什么,紧急上线还是等待发版。
##避坑
踩了两次坑,这里是要总结下该怎么做了。
###总结问题
问题主要来源于git团队协作过程中对流程认识不清晰,同时对Git的认知也不清楚,这里自己记住几个原则:
- master最稳定,master上的代码一定是最稳定的,不容许任何错误。
- dev最全,无论如何dev上应该时刻保证最新最全。
- hotfix,feature,release三个分支都是暂时分支。hotfix从master拉取,feature从dev拉取。
- 尽量避免双向merge,单向为dev和master去merge,其它三种分支尽量不要merge别的分支
- 区别本地行为和线上行为。
###最佳实践
刚好,使用我这个大反例,武哥培训了下git flow,最佳流程和流程清单如下:
GIT 团队最佳实践 https://yq.aliyun.com/articles/137035
从该篇实践可以发现一个新工具GIT FLOW,下载及环境搭建方式如下所示:
GIT FLOW 环境搭建:https://blog.csdn.net/guowenyan001/article/details/50172765
当然你有可能忘了git flow流程,这里有备忘清单:
GIT流程清单: https://danielkummer.github.io/git-flow-cheatsheet/index.zh_CN.html
记住一点,git flow hotfix name finish 的时候,远程publish上去的该hotfix分支连同本地的也会一起被删除哦:
###git rebase使用
在使用 Git 作为版本控制的时候,我们可能会由于各种各样的原因提交了许多临时的 commit,而这些 commit 拼接起来才是完整的任务。那么我们为了避免太多的 commit 而造成版本控制的混乱,通常我们推荐将这些 commit 合并成一个。
来自segmentfault大神 https://segmentfault.com/a/1190000007748862
这个命令我亲测可用,团队开发过程中不管是hotfix还是开发feature最好一次只提交一个commit,这样历史可溯源,这点非常重要!