























在本系列的前面四篇文章中已经介绍了 Git 和 GitHub 的一些特性和常用操作。本篇文章中我将介绍分支管理策略。 分支管理在代码管理中可以保证代码版本管理的清晰合理,同时也对生产版本提供有效的保护。 良好的分支管理也可以最大化的保证团队协同合作的有效进行。 本文将介绍为什么我们需要使用合理的分支策略,以及两种常见的工作流分支管理策略。
一个产品的生命周期里往往同时存在多个不同的发行版本,同时也存在着诸如开发版本、预生产版本等多个版本。 我们需要设计一个良好的分支管理策略来有效管理同时存在的多个版本,同时,实际项目中往往需要多个开发者协同开发,多名开发者之间的工作又往往互相依赖。 如何保证提交的代码的完整性,同时又能让某一功能开发者在不受其他功能开发影响的情况下自己也能独立开发,此时我们需要分支管理策略来更好的保证协同开发和独立开发互不冲突。
根据我的实践经验总结下来,分支管理的作用大致包含:代码管理与产品生命周期相结合、分支保护、协同合作与独立开发互不冲突。
不同的分支往往代表着产品的不同生命周期阶段。图 1 展示了一个简单的产品新版本发布的生命周期模型和下文 Git Flow 分支管理策略 章节中不同类型分支的对应关系。
图 1. 产品生命周期模型和分支管理对应关系 
只有将不同的分支类型与产品的生命周期对应起来,才能更好的对不同周期的代码进行不同的策略管理。
产品不同生命周期也往往需要不同的保护策略来确保代码的版本管理清晰,各版本之间的代码不会混淆甚至于破坏了生产环境的代码。分支管理的重要意义在于生产版本、预生产版本、开发版本的代码隔离,使得版本的完整性和质量都得到保证。由此我们也可以看到分支管理的保护作用可归纳为:
设想如果我们没有不同类型的分支管理策略,而只使用一个 master 分支来管理代码库,这时当我们需要发布新版本时,为了保证新发布版本不包含多余的代码,我们需要开发者禁止向 master 分支提交代码直到版本发布成功,这样严重影响了开发者对未来版本的功能开发。但是通过不同类型的分支管理,开发者既可以在 dev 分支上进行常规提交,又可以灵活地在功能分支上进行独立开发。团队内成员的各项开发工作也不会受到互相依赖,使得协同合作与独立开发互不冲突的进行下去。
Vincent Driessen 在 2010 年提出了一种 Git 工作流的分支管理模型。这种模型考虑了产品生命周期中的多种代码版本形态,能够很好地适用于大部分企业级产品中。本节我将简单介绍该分支管理策略,如果感兴趣,您也可以去阅读 Vincent Driessen 的原文:A successful Git branching model 。
图 2. Git Flow 分支管理

我们从上图 2 可以看到该策略一共有五种不同的分支类型,其中根据他们的生命周期又可以分为两大类:
长生命周期分支:项目开始一直存在的分支。
短生命周期分支:根据不同需求创建的分支,在合并到 master 或 dev 分支之后需要删除的分支。
注意 : 虽然在创建 Git 或 GitHub 仓库时,Git 或 GitHub 为我们创建了一个默认的 master 分支(现在改为了main),但是该 master 分支与其它分支并没有任何本质上的区别。在实践中我们可以使用任何的名字来替代 master、dev 分支等。例如使用 stable 表示生产分支、使用 new 表示在开发分支等。
从不同的分支类型可以看到,该策略覆盖了产品生命周期的各个阶段:开发、测试、版本发布、修复等等。因此该分支策略可以适用于大部分企业产品。下表 1 总结了 5 种分支类型的创建时间、代码来源等特点。
表 1. 5 种分支类型总结
| 类型 | 从哪个分支创建 | 什么时候创建 | 合并到哪个分支 | 什么时候删除 | 分支数量 |
|---|---|---|---|---|---|
| master | NA | 项目最开始 | NA | 永不删除 | 一个 |
| dev | NA | 项目最开始 | NA | 永不删除 | 一个 |
| release | dev 分支 | 准备发布新版本 | dev, master | 正式发布新版本,代码合并到 dev 和 master 之后 | 数量不定 |
| feature | dev 分支 | 新功能需要较长时间的协同开发 | dev | 新功能开发完成,合并到 dev 之后 | 数量不定 |
| hotfix | master 分支 | 当生产版本报出 bug | dev, master | 修复经过测试,代码合并到 dev 和 master 之后 | 数量不定 |
实际上我的项目情况相比该策略会更复杂,例如我们的产品会同时存在多个不同的生产版本,针对不同的版本可能会提交不同的修复,因此这要求我们的生产版本需要一直存在,而我们的 release 分支不再是预生产分支而是生产分支,同时也不会随着合并到 master 而消亡,而根据生产版本在线上情况会长时间存在。同时我们的 hotfix 分支是直接提交到生产版本中。当然我们也要认识到,出现这种复杂情况的原因在于我们的产品历史比较长,在采用 GitHub 作为版本控制工具以前,产品的生命周期模型就已经定义下来并被长期采用。因此我们需要尽量设计一种既符合该分支策略同时又能适用于我们产品生命周期的一种策略。
GitHub Flow 是 GitHub 推出的一种更加简便、敏捷并适合快速持续部署项目的分支管理策略。如图 3 所示。图 3 截取自 GitHub 官网关于 GitHub Flow 的介绍。

该工作流只有一个长期分支 master 分支,master 分支的 HEAD 指针同时也指向了最新的生产版本分支。 日常开发通过创建不同的功能分支来进行,在开发完成后通过创建 Pull Request 来尝试合并代码到 master 分支。Pull Request 是一种代码评审和代码合并的机制。经过评审通过之后的代码,才真正的合并到 master 分支,随后进行发布。(我将在本系列的第六篇文章中专门讲解代码评审和 Pull Request 的内容。)这种工作流的特点是简单、高效,特别适用于发布十分频繁的项目。
两种 Flow 的管理策略各有优缺点,也各自有不同的适用场景。
我在本篇文章中介绍了分支管理策略的重要意义,同时介绍了两种业界流行的基于 Git 或 GitHub 工作流的分支管理策略。 Git 的分支技术极大的提高了分支管理的效率。但是如何将分支管理能够更好的应用到具体的项目中,是我们从业者们需要认真思考的问题。我认为,分支策略需要服务于产品的生命周期特点。基于产品生命周期特点,选择合适产品的分支管理策略,同时我们还可能需要进行必要的改进以能够达到产品发布和产品质量的要求。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。