git分支管理

2020-06-12  本文已影响0人  龙翱天际

主流的分支管理有以下几种:

Git Flow

简介

image.png

首先,项目存在两个长期分支。

主分支master
开发分支develop

前者用于存放对外发布的版本,任何时候在这个分支拿到的,都是稳定的分布版;后者用于日常开发,存放最新的开发版。

其次,项目存在三种短期分支。

功能分支(feature branch)
补丁分支(hotfix branch)
预发分支(release branch)

一旦完成开发,它们就会被合并进develop或master,然后被删除。

Git Flow 偏向于控制管理,使用了较多的分支,流程颇为复杂。大量的团队在实践过程中也遇到了颇多问题,其中大部分来自长期存在的分支。

问题

GitHub Flow

简介

image.png
它只有一个长期分支,就是master,因此用起来非常简单。

官方推荐的流程如下:

GitHub Flow是一个更轻量级的软件开发模型。它摒弃了 Git Flow 中繁杂的分支, 只保留一个主分支 master 。开发新功能时从 master 分支上拉取 feature 分支,开发完成后发起 Pull-Request ,小组内进行评审和反馈,此时也进行 Code Review 。测试通过后合并回主分支。

相比于 Git Flow,这种方式因为省去了一些分支而降低了复杂度,同时也更符合持续集成的思想,以一张故事卡为集成的最小单位,相对来说集成的周期短,反馈的速度也快,能够及早的遇到问题并及早解决。

GitLab Flow

简介

Gitlab flow 是 Git flow 与 Github flow 的综合。它吸取了两者的优点,既有适应不同开发环境的弹性,又有单一主分支的简单和便利。它是 Gitlab.com 推荐的做法。

上游优先

Gitlab flow 的最大原则叫做"上游优先"(upsteam first),即只存在一个主分支master,它是所有其他分支的"上游"。只有上游分支采纳的代码变化,才能应用到其他分支。

Chromium项目就是一个例子,它明确规定,上游分支依次为:

  1. Linus Torvalds的分支
  2. 子系统(比如netdev)的分支
  3. 设备厂商(比如三星)的分支

持续发布

Gitlab flow 分成两种情况,适应不同的开发流程。

image

对于"持续发布"的项目,它建议在master分支以外,再建立不同的环境分支。比如,"开发环境"的分支是master,"预发环境"的分支是pre-production,"生产环境"的分支是production

开发分支是预发分支的"上游",预发分支又是生产分支的"上游"。代码的变化,必须由"上游"向"下游"发展。比如,生产环境出现了bug,这时就要新建一个功能分支,先把它合并到master,确认没有问题,再cherry-pickpre-production,这一步也没有问题,才进入production

只有紧急情况,才允许跳过上游,直接合并到下游分支。

版本发布

image

对于"版本发布"的项目,建议的做法是每一个稳定版本,都要从master分支拉出一个分支,比如2-3-stable2-4-stable等等。

以后,只有修补bug,才允许将代码合并到这些分支,并且此时要更新小版本号。

从以上三种介绍可以看出复杂性从高到低:Git Flow > GitLab flow > GitHub Flow

Trunk Based Development

image.png

顺着持续集成的思想,如果我们把上一种分支模型做得再极致一点,我们不要 Feature 分支,或者把 Feature 分支只留在本地;不需要使用 Pull-Request 而是直接 Push 到远程 Master 分支,我们就做到了 Trunk based Development。

使用主干开发后,我们的代码库原则上就只能有一个 Master 分支了,所有新功能的提交也都提交到 Master 分支上,没有了分支的代码隔离,测试和解决冲突都变得简单,持续集成也变得稳定了许多,问题也接踵而至,主要有以下三个:

如何避免发布引入未完成 Feature

答案是: Feature Toggle

既然代码要随时保持可发布,而我们又需要只有一份代码来支持持续集成,在代码库里加一个特性开关来随时打开和关闭新特性是最容易想到的也是最容易被质疑的解决方案。

Feature Toggle 是有成本的,不管是在加 Toggle 的时候的代码设计,还是在移除 Toggle 时的人力成本和风险,都是需要和它带来的价值进行衡量的。事实上,在我们做一个前端的大特性变更的时候,我们确实没有因为没办法 Toggle 而采用了一个独立的 Feature 分支,我们认为即使为了这个分支单独做一套 Pipeline,也比在前端的各种样式间添加移除 Toggle 来得简单。但同时,团队商议决定在每次提交前都要先将 Master 分支 Merge 到 Feature 分支,以此避免分支隔离久以后合并时的痛苦。

如何进行线上 Bug Fix

在发布时打上 Release Tag,一旦发现这个版本有问题,如果这个时候Master分支上没有其他提交,可以直接在 Master 分支上 Hot Fix,如果 Master 分支已经有了提交就要做以下三件事:

线上 Fix 通常都比较紧急。看完这个略显繁琐 Bug Fix 流程,你可能会问为什么不在 Release 分支直接 Fix,再合并到 Master 分支?

这样做确实比较符合直觉,但事实是,如果在 Release 分支做 Fix,很可能会忘了 Merge 回 Master,试想深夜两点你做完 Bug Fix 眼看终于上线成功,这时的第一反应就是“终于可以下班了。什么,Merge 回 Master? 明天再来吧“ 等到第二天你早已把这个事忘得一干二净。而问题要等到下一次上线才会被暴露出来,一旦发现,而这个时候上一次 Release 的人又不在,无疑增加了很多工作量。

如何重构

这里指的是比较大规模的重构,无法在一次提交完成,TBD 要求每一次提交都是一个可上线的版本,所以这同时还意味着这个重构无法再一个上线周期内完成。

这种情况,需要在代码设计中增加一个抽象层,保证在重构过程中先不动原来的代码,也不破坏既有功能,类似于蓝绿部署中的负载均衡器的作用,这样的流程就是:

image

以上过程也叫:抽象模拟分支

参考资料:
http://www.ruanyifeng.com/blog/2015/12/git-workflow.html
https://www.codercto.com/a/38021.html

上一篇 下一篇

猜你喜欢

热点阅读