一个成功的 Git 分支模型(适用于商业应用开发)

在这篇文章中,我将推广一下大约一年前我介绍过的一些项目(公私皆有)中使用的开发模型,它们的结果都非常成功。有段时间我非常想写出来分享一下,但是我至今才抽出时间来。我不会言及任何项目细节,仅讨论分支策略和发布管理。

为何使用 git?

关于 Git 和集中式源码版本控制系统的优缺点对比讨论,  此 web。这里有很多精彩激烈的论战。作为一名开发者,现在我更偏好使用 Git 。Git 真的改变了开发者关于合并和分支的认知。我来自传统的 CVS/Subversion 世界,合并/分支是件恐怖的事情 (「小心合并冲突,它们会反噬你!」),而且大家偶尔才会做这件事。

但是使用 Git,这些操作就显得轻而易举,它们会成为你 日常 工作流的核心部分。例如,在 CVS/Subversion 手册中,分支和合并直到最后章节才首次出现(仅供高级用户参考),但是在 每个 Git 手册中,第三章就覆盖到了(基本上)。

因为具有简单和可重复的基因,分支和合并不再是什么值得担心的问题了。版本控制工具应该专注于分支/合并,而非其他事情。

关于工具的了解已经够了,那么我们就开始进入开发模型了。这个我要介绍的开发模型,不过是每个团队成员进入软件开发流程之前必须遵循的规范。

去中心化和中心化

基于一个「真正」中心库的这种分支模型可以让我们很好的协同工作。注意这个库仅仅是被认为一个中心库(因为 GIT 在技术角度并没有中心库这一说法)。我们将此仓库命名为 origin,因为这名字被 Git 用户熟知。

!

所有开发者都从 origin 库拉取或向其推送代码。在中心化的推送-拉取关系之外,开发者也可以从其他的开发者库拉取代码更改。例如,为了开发一个大型功能,有多位开发者组成一个开发小组,在功能完成之前,开发过程不必推送至 origin 库。在上面的图中就有 Alice 和 Bob, Alice 和 David,还有 Clair 和 David 之间组成的小组。

技术层面,Alice 要在本地库加一个远程 Git 分支并命名为 bob,指向 Bob 的仓库。其他人也一样。

主分支

git 的核心在开发模式上受到了现有模式的极大启发,中心仓库在整个生命周期保持了两个主要的分支:

  • master
  • develop

每个 Git 用户都对在 origin 的  master 分支很熟悉。 跟 master 分支并行的是另一个称为 develop 的分支。

我们称 origin/master 为主分支,这个分支源码的 HEAD 一直指向 可用于生产环境 的状态。

我们称 origin/develop 为主分支,这个分支源码的 HEAD 总是反映下一个版本的最新开发状况。有些人称这个分支为 "整合分支" 。所有的每日自动构建都是从这儿构建的。

当 develop 分支上的源代码达到一个稳定点并准备发布时, 所有的更改都应该以某种方式合并回 master 分支, 然后使用发行版本进行标注。 接下来将从细节上讨论这是如何完成的。

因此, 每次将变更合并回 master分支时, 这是一个 根据定义 的新产品发布。 我们趋向于对此非常严格,因此理论上来讲, 我们可以在每次提交到 master 分支时, 使用一个 Git 钩子脚本来自动完成构建和发行我们的软件到生产服务器。

辅助分支

在讨论完 master 分支和 develop 分支后,将要讨论的多样化的辅助分支,支持成员间并行开发, 轻松跟踪功能开发、生产版本发布、还能快速修复生产环境中产生的 Bug 。和主分支不同的是,辅助分支只有有限的生命周期,通常在完成使命后会被删除。

可能用到的辅助分支分类有:

  • 功能分支
  • 发布分支
  • 修复 Bug 分支

每个分支都有特殊的用途。这些分支的来源分支和他们要合并回的分支都有严格的定义。在后面我们再具体讨论。

技术上,辅助分支都没有特殊含义。我们就是根据具体使用功能对辅助分支进行分类。辅助分支和普通的 Git 分支没有区别。

功能分支

!

功能分支可能源自于:

develop 分支

功能分支必须合并回:

develop 分支

功能分支命名惯例:

任何名字都可以,但不能包含 master, develop, release-*, 或者 hotfix-*

功能分支(或称为特性分支)是被用来开发新功能的,这些新功能是要即将上线或更长时间后发布的。功能分支创建后开始开发时,之后将要合并的时间点是不知道的。功能分支的精髓是伴随开发过程一直存在,但是肯定会被合并回 develop (在下一个预期的发布版本中清晰的添加新功能 ) 或被丢弃 (万一实验不尽如人意)。

功能分支通常存在开发人员的仓库中,不会出现在 origin 仓库。

创建一个功能分支

当我们开始写一个新的功能时,请从 develop 分支中切换出来

$ git checkout -b myfeature develop
Switched to a new branch "myfeature"

在开发中加入已经完成的功能

完成的功能可能被合并进入 develop 分支中,以确保他们会被添加到即将发布的版本中去

$ git checkout develop
Switched to branch ‘develop‘
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

--no-ff 标记将会在分支合并的时候在创建一个新的提交对象,即使这次合并可以使用 fast-forwark方法进行提交。这就可以避免丢失功能分支的历史信息并且可以把所有的功能在叠加在一起提交上去,请看图片对比:

!

在后一种情况中,从 Git 历史中是无法查看到是哪几个提交对象在一起实现了一个功能 -——您必须手动读取所有日志消息。还原整个功能(即一组完整的提交)在后一种情况下是真的让人很头疼的事情,但是如果使用使用 --no-ff 标志,就可以很容易完成这个任务的。

当然啦,它虽然创作更多的空的提交对象,但是增益却远远大于成本。

发布分支

该分支可能源自于:

develop 分支

必须合并到:

develop 和 master 分支

分支命名习惯:

release-*

发布分支(Release branches) 支持新产品发布的准备。 它们允许在最后一刻追求细节。此外,它们允许小错误修复以及为发布准备元数据(版本号,构建日期等)。通过在发布分支上做的这些工作, develop 分支被清除以接收下一个大版本的功能特性。

从 develop 分支检出一个新发布分支的重要时刻就是当开发(基本上)反映了新版预期状态的时候。 至少,在那时,所有以『即将构建的发布版』( release-to-be-built )为目标的功能特性必须合并回 develop 分支。 针对未来版本的所有功能则可能不会 —— 它们必须等到发布分支检出以后才可以这么做。

正是在发布分支的开始,即将发布的版本才会被分配一个版本号 —— 一个前所未有的版本号。直到那一刻,develop 分支才反映了『下一版』的变更,但在发布分支开始前,对于『下一版』最终会是 0.3 版还是 1.0 版仍然是不明确的。该决定是在发布分支开始时进行的,并且由项目关于版本号碰撞的规则来执行。

创建一个发布分支

发布分支源于 develop 分支。举个栗子,假设我们当前发布的产品版本为 1.1.5 ,并且即将发布一个新的大版本。 develop 分支已经为『下一版』做好了准备,我们决定把版本号改成 1.2(而不是 1.1.6 或者 2.0)。那么,我们要做的只是检出发布分支并给它一个可以反映版本号的名字:

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)

在创建完新分支并切换到该分支后,我们需要碰撞版本号。在这个例子里, bump-version.sh 是一个虚构的脚本文件,用以改变工作副本中的一些文件来反映新版本。(当然也可以手动啦,重点是 那些 改变的文件)然后,碰撞后的版本号就被提交了。

直到确定会推出发布版的这段时间里,新分支都会一直存在。在此期间,bug 修复可能会应用到这个分支上(而不是 develop 分支)。 严禁在此分支添加大的新功能特性。 这些分支必须合并回 develop 分支,然后,等待下一个大版本的到来。

完成并发布你的分支

当你真的准备好要发布分支的时候,还需要执行一些别的操作。首先,发行版必须合并进 master 分支中(一定确保每次提交到 master 分支的都是最新的版本)。接下来,请一定标记对 master 分支的更新记录,用于以后查看该版本时进行参考。最后, 发布新分支所做的更改需要重新合并为 develop 分支,以确保以后的版本也修复了这些错误。

Git 中的执行以下两个步骤:

$ git checkout master
Switched to branch ‘master‘
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2

至此,这个版本已经完成修改,并且用作将来的参考版本。

注: 你可能还想要使用 -s 或者 -u <key> 来加密签名。

为了保持发布分支所做的更改一致,我们需要将这些更改合并到 develop 分支中。在 Git 中执行:

$ git checkout develop
Switched to branch ‘develop‘
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)

这一步可能会导致合并冲突(可能是因为我们已经更改了版本号)。如果是这样,尝试修复它并再次提交。

现在我们已经完成了所有步骤,发布分支可以被删除了,因为我们不再需要它了:

$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).

热修复分支

!

分支可能来自于:

master

必须合并到:

develop 和 master

分支命名惯例:

hotfix-*

热修复(hotfix)分支和发布(release)分支很像,因为它们都意味着即将有新的生产版本发布,尽管不是意料之中的。它们产生的原因是现有的生产版本出现了不受欢迎的情况,从而必须立即起作用。当生产版本中的一个严重的 bug 必须马上被修复,热修复分支可能从 master 分支上用于标记生产版本的对应标签上创建分支。

其本质是当有人准备对生产版本进行快速修复时,团队成员(在 develop 分支)可以继续工作。

创建修复 bug 分支

修复 bug 分支创建于 master 分支。 例如,1.2版本是当前生产环境的版本并且有 bug 。但是 develop 分支上的修改还不够稳定。这时我们可以创建一个修复 bug 分支来解决这个问题:

$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)

不要忘记在关闭分支后更新版本号!

然后,修复 bug ,一次提交或多次分开提交。

$ git commit -m "Fixed severe production problem"
[hotfix-1.2.1 abbe5d6] Fixed severe production problem
5 files changed, 32 insertions(+), 17 deletions(-)

完成一个修复 bug 分支

当完成一个修复 bug 分支之后,bug 分支需要合并到 masterdevelop 分支上,以保证在下一版本中也包含该 bug 修复。 这与完成发布分支完全相似。

首先,更新 master 并对这次发布打上 tag 。

$ git checkout master
Switched to branch ‘master‘
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2.1

注: 你可能还想要使用 -s 或者 -u <key> 来加密签名。

然后,在 develop 分支里包含 bug 修复分支的改动:

$ git checkout develop
Switched to branch ‘develop‘
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)

对于上面的规则,有一点是例外的: 当发布分支已经存在时, bug 修复分支的改动应该合并到该发布分支,而不是 develop 分支。当发布分支完成的时候, 把 bug 修复分支反向合并到发布分支中,最终也会导致 bug 修复被合并到 develop 分支中去。(如果 develop 分支中的工作马上就要这个 bug 修复的改动并且不能等待发布分支完成,那么现在你也可以安全地将 bug 修复合并到 develop 分支中去。)

最后,移除临时分支:

$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).

小结

虽然这种分支模式目前看来已经不是什么新鲜事了,但这篇文章开头的 「大图」已经证明,这种模式对我们的项目实实在在的是非常有用。它形成了一个优雅并且更加容易理解的模型,并且能加强团队中成员们对于分支和其释放过程的理解。

这里提供给大家上面大图更加清晰的 PDF 版本,建议把它打印出来挂在墙上膜拜并且以便开发过程中快速查看。

更新: 如果有人需要这张图片: 这里附上下载文件 gitflow-model.src.key

Git 分支模型.pdf 下载

更多现代化 PHP 知识,请前往 Laravel / PHP 知识社区

原文地址:https://www.cnblogs.com/summerblue/p/8940028.html

时间: 2024-08-05 12:57:32

一个成功的 Git 分支模型(适用于商业应用开发)的相关文章

(转载)介绍一个成功的 Git 分支模型

介绍一个成功的 Git 分支模型 在这篇文章中,我提出一个开发模型.我已经将这个开发模型引入到我所有的项目里(无论在工作还是私人)已经一年有余,并且它被证明是非常成功的.我打算写这些已经很久了,但我一直找不到时间来做,现在终于有时间了.我不会讲任何项目的具体细节,仅是关于分支策略和释放管理相关内容. 它主要体现了Git对我们源代码版本的管理. 为何是Git? 对于Git与其他集中式代码管理工具相比的优缺点的全面讨论,请参见这里.这样的争论总是喋喋不休.作为一个开发者,与现今的其他开发工具相比较,

一个成功的 Git 分支模型

本文由 伯乐在线 - henry 翻译,sunbiaobiao 校稿.未经许可,禁止转载! 在这篇文章中介绍的开发模型在大约一年前已经在我的私有项目和工作引入的,而且已经被证明是非常成功的.我想写一些关于这个模型的东西已经好一段时间了,但是一直苦于没有时间,不过现在可以了.我不想探讨任何项目细节,只讨论分支策略和发布管理. 这篇文章围绕着Git做为我们所有的源代码版本控制工具而展开的. 为什么是Git 为了深入探讨git和集中式源码版本控制系统的利弊,参见这些文章.这方面有太多的激烈争论.作为一

【转】一个成功的Git分支模型 .

---恢复内容开始--- 能力所限,本文的翻译多处都很不地道,如果哪些地方难于理解,还烦请查看原文.—— Dbzhang800 20110921 在本文中,我向大家介绍的是在大约一年前我为自己的项目(包括工作和私人项目)引入的且已被证实非常成功的一个开发模型(development model).这段时间我一直想写点关于它的东西,但在此之前,我却从未能抽出充足的时间来完成这件事.我不会谈论项目的任何细节,只涉及分支策略(branching strategy)和发布管理(release manag

介绍一个成功的 Git 分支模型 Release 分支

英文原文: http://nvie.com/posts/a-successful-git-branching-model/ 中文版: 在这篇文章中,我提出一个开发模型.我已经将这个开发模型引入到我所有的项目里(无论在工作还是私人)已经一年有余,并且它被证明是非常成功的.我打算写这些已经很久了,但我一直找不到时间来做,现在终于有时间了.我不会讲任何项目的具体细节,仅是关于分支策略和释放管理相关内容. 它主要体现了Git对我们源代码版本的管理. 为何是Git? 对于Git与其他集中式代码管理工具相比

Git 分支模型

翻译自:https://nvie.com/posts/a-successful-git-branching-model/ 在这篇文章中,主要介绍 Git 分支模型.不会谈论任何项目的细节,只讨论分支策略和发布管理. Git分布式和集中式理解 我们配置了中央存储库可以很完美的配合该分支模型工作.这里需要注意下,这个仓库只是被认为 是中央仓库(因为Git是DVCS(分布式版本管理系统),在技术层面上没有中央仓库).我们将这个中央仓库称为origin,应该所有Git用户都熟悉这个名称. 每个开发人员都

Git分支模型

本文介绍一种使用Git进行源代码管理的分支模型,着重于如何使用Git更好的管理我们的源代码. 我假定您对Git有一定了解,会使用基本的Git命令进行一些简单的源代码管理工作.这不是一篇Git使用教程. 文章的主要思想源自以下链接: http://nvie.com/posts/a-successful-git-branching-model/ 根据自己的使用情况进行了补充. 我们知道Git是一个不需要中心服务器就能工作的源代码管理系统:但我仍然建议你至少保持一个逻辑上的中心服务器来存放你的长期分支

Git 分支模型与开发规范

01.分支模型 master:长期分支,一般用于管理对外发布版本,每个 commit 对一个 tag,也就是一个发布版本 develop:长期分支,一般用于作为日常开发汇总,即开发版的代码 feature: 短期分支,一般用于一个新功能的开发 hotfix :短期分支 ,一般用于正式发布以后,出现 bug,需要创建一个分支,进行 bug 修补. release :短期分支,一般用于发布正式版本之前(即合并到 master 分支之前),需要有的预发布的版本进行测试. master和develop作

Git详解之三 Git分支

相关文档 — 更多 Git 基础培训.ppt GIT 使用经验.ppt GIT 介绍.pptx GIT 分支管理是一门艺术.docx Eclipse上GIT插件EGIT使用手册.docx git/github学习笔记.doc git 版本控制系统.docx Git开发管理之道.pdf Git内部培训资料.pptx Git权威指南-第5篇-第32章-Gerrit.pdf Gitolite 构建 Git 服务器.pdf 版本控制之道 - 使用Git.pdf Git使用指南(中文).pdf Git-C

Git flow的分支模型与及常用命令简介

Git flow是git的一个扩展集,它基于Vincent Driessen 的分支模型,文章"A successful Git branching model"对这一分支模型进行了描述,其示意图如下: Git flow的源码可以通过以下链接下载: https://github.com/nvie/gitflow 或者,直接输入以下命令安装git flow: apt-get install git-flow 在Windows平台下安装git flow,可以参考<Windows环境下