-->

左耳听风_021_20_Git协同工作流你该怎么选

你好,我是陈浩网名猪耳朵house.与传统的代码版本管理工具相比呢,塔有很多的优势,所以越来越成为程序员喜欢的版本管理工具。

那我觉得呀get这个代码版本管理工具最大的优势呢有这么几个。

那第一呢get呢是一个分布式的版本管理工具,而且啊可以是单机版的。

所以你在没有网络的时候啊,同样可以提交代码。

那对于我们来说呢啊这意味着在出差途中啊,或者是没有网络的环境中啊,依然可以工作写代码。

那这是不是听起来有点不对呢?一方面呢以后你再也不能以没有网络作为不能工作的借口了。

那另一方面呢,没有网络意味着没有google和stack of flow啊,光有个本地的gate,我一样不能写代码啊,好吧,这已经超出了gate这个技术的范畴了啊,这里啊就不讨论了。

那第二个优点呢,是啊从一个分支向另一个分支合并代码的时候呢,会把要合并的分支上的所有提交啊一个一个的应用到被合并的分支上。

那合并后呢,也能看得到整个代码的变更记录,而其他的版本管理工具呢就不能这样。

那第三个优点呢就是gate切换分支的时候啊,通常很快不像其他版本管理器啊,每个分支啊都需要一份copy.那最后呢gate有很多非常有用的命令啊,可以让你很方便的工作。

比如我呢就很喜欢gate stash命令,它可以把当前没有完成的事啊,先暂暂一下,然后去忙别的事儿。

而gate cherry pick命令呢,可以让你有选择的合并提交。

Gate add杠p呢可以让你挑选改动的提交。

而gate grap呢可以用来在所有提交中啊找代码,因为都是本地操作,所以你会觉得速度飞快。

那除此之外呢,由gate衍生出来的gay lab和github也能帮你很好的管理编程工作,比如vki、 YK、 gaproquest,还有一手等等,集成了与编程相关的工作。

让人觉得啊这不是一个冷冰冰的工具,是真正和我们日日工作发生了很好的交互。

那giay hub和gay lab这样工具的出现呢,让我们的工作啊可以呈现在一个工作平台上,并且啊可以以此来规范整个团队的工作。

而这个呢才正是gate这个版本管理工具成功的原因。

那今天呢我们不讲gate是怎么用的?因为互联网上有太多的文章和书了,而且如果你现在还不会用gate,那么我觉得你啊已经严重落后于这个管代了。

那在这节课中呢,我想讲的是gate的协同工作流。

因为我看到很多的团队啊,在使用gate的时候呢并没有用好。

但目要注意啊,因为get呢是一个分布式的代码管理器,那是分布式呢就会出现数据不一致的情况。

所以呢我们需要一个协同工作流来让工作变得高效,同时呢可以有效的让代码具有更好的一致性。

那说到一致性呢,就是每个人手里的开发代码,还有测试和生产线上的代码,要有一个比较好的一致性的管理和协同方法。

那这个呢就是gate协同工作流需要解决的问题。

就目前来说呢,你可能以为我想说的是gate flolow工作流啊,恭喜你猜对了。

但是呢我想说的是,gate flow工作流太过复杂,那我并不觉得gate flow工作流啊是一个好的工作流。

如果你的团队在用这种工作流开发软件,我相信你的感觉啊一定是糟透了。

所以呢这节课我会对比一些比较主流的协同工作流,然后呢再抨击一下gate flow工作流。

那们先来说一下中心式的协同工作流。

首先呢我们先说明一下啊,gate它也是可以像SN这样的中心工作流一样工作的那我相信啊很多程序员都是在采用这样的工作方式,那整个过程呢一般是这样的。

首先我从服务器上通过get put把代码同步下来,改完之后呢,通过get comit提交到本地仓库中,然后呢我再push到远程仓库中。

那这样呢其他同学啊就可以得到你的代码了。

那如果在第三步发现push失败了啊,因为别人已经提交了,那么呢你就需要先把服务器上的代码给铺下来。

那为了避免有味儿的动作呢,你可以使用get put杠rebase.那这样呢就可以把服务器上的代码提交啊,直接合并到你的代码中。

那对此呢get的操作是这样的。

首先呢把你本地提交的代码呢先放到一边,然后呢把服务器上的改动啊下载下来。

最后呢在本地把你之前的改动,再重新一个一个的做comit啊,直到全部成功。

你可以参考文中的这张图,get呢会把origin master的远程分支啊下载下来,然后呢把本地的master分支上的改动啊,再一个一个的提交上去。

那如果有冲突呢,你就需要先解决冲突。

然后呢说gay rebase continue,那gate在做pull base的时候呢,会一个一个的应用本地提交的代码。

那如果有冲突呢,就会停下来啊等你来解决冲突。

那以上所说的这种方式呢,有一个问题就是大家啊都在同一个主干上开发程序。

那对于小团队或者小项目你可以这么干。

但是对于比较大的项目或者是人比较多的团队呢呢是代代码,会会有很多的问题。

那最大的问题呢就是代码可能干扰太过严重了。

尤其是我们想安安静静的开发一个功能的时候,那我们需要把各个功能代码变动隔离开来。

那同时呢各个功能又会有多个开发人员啊开开发。

那个时候呢,我们并不想让各个功能的开发人员呢都在master分支上共享他们的代码。

我们想要的协同方式呢是让同时开发一个功能的开发人员呢可以分享自己的代码。

但是呢不会把代码分享给开发其他功能的开发人员。

那直到整个功能开发完毕之后呢,才会分享给其他的开发人员。

所以呢我们需要引入功能分支。

那这个协同工作流的开发过程啊是这样的。

首先呢使用gaate check out命令啊,创建new feature分支,然后呢共同开发这个功能的程序哈,就在这个分支上工作进行add commit等等操作。

然后呢我再通过get push命令,把这个分支的代码push到服务器上之后,其他程序员啊就可以通过get pool rebase来拿到这个分支的最新的代码。

最后呢通过request的方式做完code review之后呢,合并到master分支上。

那就像文中的这张图一样,紫色的分支呢就是功能分支合并之后呢,就是这个样子的。

我们要明白啊,其实这种开发也是以服务器为中心的开发,还不是这个分布式开发,它只不过是用分支啊来完成代码改动的隔离。

另外呢我想提醒一下,为什么会叫功能分支,而不是叫项目分支。

因为gate的最佳实践呢是希望大家在开发过程中啊快速提交,快速合并,快速完成。

那这样呢可以少很多冲突的事儿,所以啊就叫功能分支。

那传统的项目呢分支开的太久,时间越长就越合不回去。

那gate里面这种玩法呢,其实就是让我们啊把一个大项目切分成很多小项目来执行。

那这样呢才是互联网式的快速迭代式的开发流程。

那接着呢我们再来说一说开篇提到的啊gate flow协同工作流。

在真实的生产过程中呢,前面所讲的协同工作流啊还是不能满足工作的要求。

而这主要是因为我们生产过程啊是比较复杂的。

软件生产中呢会有各式各样的问题,并且啊还要面对不同的环境。

我们要在不停的开发新代码的同时呢维护线上的代码。

于是呢就有了这样一些需求。

首先我们希望有一个分支啊是非常干净的,于面是可以发布的。

代码上面的改动呢永远都是可以直接发布到生产环境中呢。

那这个分支上不能有中间开发过程中不可以上生产线的代码提交。

然后呢,我们希望当代码达到可以上线的状态的时候呢,也就是在阿尔法或者贝塔release的时候,在测试和交付的过程中啊,依然可以开发下一个版本的代码。

那最后呢我们还希望那对于已经发布的代码呢也会有一些bug face改动。

但是它不会把正在开发的代码啊提交到生产线上去。

你看面对这些需求啊,前面所说的那些协同方式啊就全都不行了。

因为我们啊不仅是要在整个团队中共享代码,我们要的呢更是管理好不同环境下的代码,不互相干扰。

那说的技术一点就是我要管理好代码与环境的一致性。

那为了解决这些问题呢,gate flow协同工作流就出来了。

那gate flow协同工作流呢是在二零一零年,you wson and jason在a successful gay branching model这篇文章里面啊介绍给世人的那整个协同工作流的核心思想呢,我用一张图在文中啊表示了出来。

那整个代码库中呢一共有五种分支。

那第二个呢是master分支,也就是主干分支用于发布环境上面的每一次提交啊都是可以直接发布的那第二个呢是feature分支,也就是功能分支用于开发分支,那它对应的是开发环境。

第三个呢是develop分支,也就是开发分支。

那一旦功能开发完成,就像develop分支啊合并合并完成之后呢,删除掉功能分支。

那这个分支呢对应的就是集成测试环境。

第四个呢是release分支。

当develop分支测试达到可以发布的状态的时候呢,就开出一个release分支,然后呢做发布前的准备工作。

那这个分支啊对应的是预发布环境。

那之所以需要这个release分支呢,是因为这样我们的开发啊就可以继续向前,不会因为要发布而被block住,导致不能提交。

那一旦release分支上的代码达到可以上线的状态,那么我就需要把release分支向master分支和develop分支啊,同时合并来保证代码的一致性。

然后呢我再把release分支啊删除掉。

最后呢第五个分支啊是hospfix分支,是用于处理生产线上的代码的bug fix.每个线上代码的bug fix啊都需要开一个hot fix分支。

那完成之后呢,向developer分支和master分支上合并合并,完成之后呢,再删除掉hot fix分支。

那这个呢就是整个协协同工作一个工作过程,我们可以看到这么几点。

那第一点呢就是我们需要长期维护gffmaster和developer这两个分支。

那第二点呢就是这个方式啊还是有一定复杂度了,尤其是release和hold fic分支,需要同时向两个分支做合并。

所以呢如果你没有一个好的工具来支撑的话,就有可能因为我们忘了做一些操作而导致代码不一致。

那跟flow协同虽然工作流比较重,但是呢它几乎可以应对所有公司的各种开发流程,包括瀑布模型或者是快速迭代模型。

那接下来呢我们再介绍一种工作流,叫get up啊,或者是gate lab协同工作流。

对于gate flow来说呢,虽然可以解决我们的问题,但是他自己啊也有很多的问题。

在gate flow流行了一段时间之后呢,圈内啊就出现了一些不同的声音。

我在文中呢给了两篇吐槽文章的链接啊,你可以点开看一看。

那其中有一个问题呢,就是因为分支太多啊,所以会出现gate log混乱的局面。

那具体来说呢,主要是gate flow,它使用的是gate march no FF命令来合并分支。

那这样的话,在gay floor这样多个分支的环境之下呢,会让你的分支管理的log啊变得很难看。

比如文中的这张图,这里面的no FF参数呢就是no fast forward的意思。

也就是说合并的方法是不要把这个分支的提交啊以前置的方式来合并,而是留下一个merge的提交,这是把双刃剑。

我们希望我们的no FF啊,你像图中右边那样,而不是像左边那样。

那对此我的建议呢是只有feature合并到develop分支的时候啊,才使用no FF参数。

那其他合并啊都不使用no FF参数来做合并。

那另外呢还有一个问题,就是在开发的足够快的时候呢,你会觉得同时维护master和develop两个个支啊啊是一件无聊的事儿。

因为这两个个分啊啊在多多情况下下都一样样,包括release分支呢会觉得创建这些分支啊太过无聊。

而你的整个开发过程呢,也会因为这么复杂的管理啊变得非常复杂。

尤其是你像回滚某些人的提交的时候呢,你会发现这事儿啊似乎有点不好干了。

而且呢在工作过程中啊,你会来来回回的切换工作的分支,有时候一不小心没有切换,就提到了不正确的分支之上,你还要回滚和重新提交等等。

Gylab b一开始呢是gay a flow的坚定支持者。

后来因为这些吐槽啊,以及hacker news和ready上大量的讨论啊,gay lalab呢也开始始玩了了,他们啊也写了篇篇log g创造了一个新的worwork flow中,也就是gyub flow.那这gigiay a fflow是基于gigiha fflow来做。

那那这gigiha fflow其实也叫gilub flow low.就是在github上呢啊那个开发方式首先呢是每个开发人员啊都把官方库的代码folk到自己的代码仓库中,然后呢开发人员在自己的代码仓库里啊做开发啊,想干啥就干啥。

所以开发人员的代码库中啊需要配两个远程仓库,那一个呢是自己的库,一个啊是官方库,用户的库呢用于提交代码改动。

而官方库呢用于同步代码,然后呢我在本地建一个代码,分支啊,在这个分支上做代码的开发。

随后啊开发人员啊把这个功能分支push到自己的代码仓库中。

那接下来呢向官方客户发起proteast啊,并且做客户review.那一旦通过呢,就会向官方库进行合并,这个就是github的整个工作流程。

那如果你有官方库的权限呢,那么你啊就可以直接在官方库中啊建功能分支开发,然后提交pro quest.那通过code real之后呢,再合进master分支。

而master一旦有代码合并了,就可以马上release啊,这个是一种非常gze的玩法。

这需要一种自动化的CI和CD工具啊,做辅助。

没错啊,CI和CD啊应该是开发中的标配了。

然而gate half f low这种玩法呢依然会有好多问题。

因为它虽然变得很简单了,但是它没有把我们的代码和我们的运行环境给联系在一起。

所以呢del lab它提出了几个优化题。

那其中一个呢是引入环境分支,就像文中这张图表示的,它包含了预发布和生产分支。

而有些时候呢我们还要有不同版本的发布。

所以呢还需要有各种release的分支。

那这里呢我同样在文中啊用一张图来分明,那一aster分支呢是一个roadmap分支。

然后呢,一旦稳定了,就建一个稳定版的分支,比如二点三点stable分支,或者是二点四点stable分支。

那这其中呢可以cherry pick master分支上的一些改动过去。

那这样呢也就解决了两个问题,那一个呢是环境和代码分支对应的问题。

那另一个呢是版本和代码分支对应的问题。

老实说呢,对于互联网公司来说呢,环境和代码分支对应这个这啊只要有一个比较好的CI和CD生产线呢,这种环境分支啊应该也是没有必要的。

而对于版本和代码分支的问题呢,我觉得这个啊应该是有意义的。

但是呢最好不要维护太多的版本,版本啊,应该是短暂的。

等新版本发布的时候呢,老的版本啊就应该删除掉的那讲了这么多协同工作流呢,我想在这里啊总结一下他们的本质。

那对于上面这些各式各样的工作流的比较和思考,虽然呢我个人非常喜欢gihuflow,而且在必要的时候呢会用上给ay lab的版本或环境分支。

不过呢我们现实生活中啊还是有一些开发工作啊,不是以功能为主,而是以项目为主的。

也就是说项目的改动量可能会比较大,啊,时间呢和周期也可能比较长。

所以我在想有没有一种工作流可以面对我们现实工作中的各种情况啊,但是我想啊这个世界太复杂了,应该不存在一种一招鲜吃遍天的放置四海皆准呢银弹方案。

所以呢我们还要根据自己的实际情况来挑选适合我们的协同工作的方式。

而代码的协同工作流呢属于SEM的范畴,要挑选好适合自己的方式啊,我们需要知道软件工程配置管理的本质。

那根据这么多年来,我在各个公司的经历啊,有互联网的、有金融的,有项目的,也有快速迭代的啊等等经历。

我认为团队协同工作的本质啊不外乎这么几个事儿。

那第一呢不同的团队啊能够尽可能的并行开发。

第二呢,不同软件版本和代码的一致性。

第三呢,不同环境和代码的一致性啊,第四呢就是代码总是会在稳定和不稳定之间交替。

所以我们希望生产线上的代码总是能对应到稳定的代码上。

那基本在这四个事儿中呢,工作流呢大都是在用建立不同的分支来做到开发并行代码、环境版本一致和稳定的代码。

所以要选择适合自己的协同工作流,我们就不得不谈一下软件开发的工作模式。

首先呢我们知道软件开发的趋势啊一定是这个样子的那第一个呢是以微服务或者是SOA作为架构的方式。

一个大型软件呢会被拆分成多个服务。

那么我们的代码应该也会跟着服务拆解成多个代码仓库。

那这样一来呢,我们每个代码仓库啊都会变小,于是我们的协同工作流程啊就会变得简单。

那对于每个服务的代码,仓库呢,我们的开发和迭代速度啊也会变得很快。

那开发团队呢也会跟服务一样啊,拆成了多个小团队。

那这样一来呢,gate flow这种协同工作流啊就非常重了。

而github这种方式呢或者使用功能分支这种方式啊会更适合我们的开发。

那第二个趋势呢是以divaugus为主的开发流程。

那devors呢专注于CI和CD啊,需要我们有自动化的集成测试和持续部署的工具。

那这样一来呢,我们的代码发布速度啊就会大大加快。

每一次提交呢都能很快被完整的集成测试,并且啊很快的发布到生产线上。

于是呢我们就可以使用更简单的协同工作流程。

而不需要维护多个版本,也不需要关注不同的运行环境啊,只需要一套代码就可以了。

那get har flow或者是功能分支这种方式啊,也更适应这种开发并看啊。

如果我们把软件开发升级,并且呢简化到SOV、服务化和divorce上面来,那么协同工作流啊就会变得非常简单。

所以呢协同工作流的本质啊并不是怎么玩好代码仓库的分支策略,而是玩好我们的软件架构和软件开发流程。

那当然啊服务化和deal offs啊是每个开发团队啊需要去努力的目标。

但是就算这样啊,也是存在一些情况,需要我们用比较重的协同工作的模式。

比如整个公司啊都在做一个比较大的升级项目。

那这其中呢可能就会在代码上有一个比较大的调整,那有可能啊是一次重大的成构。

那在这个时候呢,可能还有一些并行的开发需要做,比如一些小功能的优化啊,一些线上bug的处理。

我们可能还需要在生产线上做新旧两个版本的AB测试。

那在这样的情况下呢,我们可能会或多或少的使用跟flow协同工作流。

但是呢这样的方式啊不会是常态,而是特殊时期。

我们不可能隔三差五的对系统的架构啊,或者对代码做大规模的重构。

所以在大多数的情况下,我们还是应该选择一个比较清亮的协同工作流。

而在特殊时期啊,特立特版最后呢让我用一句话来结束本节课,就是与其花时间在的协协工作流上,还不如把时间啊花在调整软件架构和自动化软件生产和运维流程上面。

那这个呢才是真正简化协同工作流程的根本。