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

---恢复内容开始---

  • 能力所限,本文的翻译多处都很不地道,如果哪些地方难于理解,还烦请查看原文。—— Dbzhang800 20110921

在本文中,我向大家介绍的是在大约一年前我为自己的项目(包括工作和私人项目)引入的且已被证实非常成功的一个开发模型(development model)。这段时间我一直想写点关于它的东西,但在此之前,我却从未能抽出充足的时间来完成这件事。我不会谈论项目的任何细节,只涉及分支策略(branching strategy)和发布管理(release management)。

它的焦点是Git,我们所有源码的版本管理工具。

为什么是git?

要找一个对Git(与集中式的源码控制系统比较)的优点和缺点的完整且透彻的讨论,可参阅这个网页。那儿的火药味很浓。作为一名开发人员,我喜欢Git胜过喜欢现有的其他所有工具。Git真正改变了开发人员对合并和分支和认识。在经典的CVS/SVN的世界中,合并/分支一直被认为有点吓人("提防合并冲突,它会咬你!"),且很少被使用的东西(每隔一段时间才可能用一次)。

但对于Git来说,这些操作是非常低廉和简单的,而且它们被认为是日常工作??流程中的核心操作之一,真的是如此。举例来说,在CVS/SVN的书籍中,分支和合并在后面章节(面向高级用户)才会被讨论,而在每一个git中,它在第3章(基础部分)已被介绍。

简单和高频率使用的结果就是,分支和合并不再是让人恐惧的事情。版本控制工具比其它工具更被寄希望于辅助分支/合并操作。

对工具的介绍够多了,让我们向开发模式进军吧。我在这儿要展示的模式,本质上不过是,为了使软件开发过程可管理,每一个团队成员要遵守的一套流程。

去中心却集中(Decentralized but centralized)

我们使用的且与本分支模型配合很好的软件仓库的配置,需要有一个中心“真”仓库。注意,它只是被考虑成中心仓库(因为Git是一个DVCS,在技术层面上并不存在一个像中心仓库这样的东西)。我们用origin指代这个仓库,因为所有的Git用户都熟悉这个名字。

每个开发者拉取(pull)并推送(push)到origin。但除了这种集中式的推送拉取关系,每个开发者也可能会从其他的开发者处拉取代码的变更,从而形成一个子团队。例如,当与两个或更多的开发者协同工作于一个大的新特性时,在将工作代码推送到持久的origin之前,这可能很有用。在上图中,Alice和Bob,Alice和David,以及Clair和David,分别构成了子团队。

从技术上讲,这只不过意味着Alice定义了一个名为bob的Git的remote,它指向了Bob的软件仓库。反之亦然。

主分支(main branches)

本质上,该开发模型是从现有的模型中获得灵感而产生的。中心仓库中维护着两个永生不灭的主分支:

  • master
  • develop

每一个Git用户应该都熟悉origin中的master分支。与master平行,还存在另一个被称为develop的分支。

我们将origin/master考虑成这样的一个主分支,其源码的HEAD始终代表了产品就绪的状态。

我们将origin/develop考虑成这样的一个主分支,其源码的HEAD总是代表已经并入了最新的开发变更的状态,这些变更将用于下次的发布。有人喜欢将其称之为“集成分支(integration branch)”。这也是自动的nightly build的源码来源。

当develop分支中的源码达到一个稳定点且准备发布时,所有的变更应当被合并回master分支,然后将打上版本号标签。至于具体是怎么实现的,接下来将进一步讨论。

因此,按(我们的)定义,每当变更被合并回master,都将导致一个新产品发布。我们倾向于采用非常严格的策略,因此理论上,我们可以使用一个Git的脚本钩子,当master上有一个提交(commit)时,可以自动构建并将软件转到产品服务器。

辅助分支(Supporting branches)

除了主分支master和develop,我们的开发模型使用了各种各样的辅助分支来——帮助团队成员间的并行开发,减轻特性的追踪的痛苦,准备产品的发布以及快速修复发布产品中的缺陷。不同于主分支,这些分支的生存周期总是有限的,因为它们最终会被移除。

我们可能用到的不同的分支类型:

  • 特性分支(Feature branches)
  • 发布分支(Release branches)
  • 快速修复分支(Hotfix branches)

这些分支中的每一个都有着特定的目的,也必须遵守严格的规则:哪些它们所起源于的分支,也是它们必须要合并到的目标分支。我们将很快将介绍一遍它们。

从技术角度看,这些分支绝没有任何“特殊性”。分支类型是依据我们的使用方式划分的。毫无疑问,它们仍是普通的Git分支。

特性分支(Feature branches)

可能起源于分支:develop

必须合并回分支:develop

分支命名惯例:除 master、develop、release-* 或 hotfix-* 外的任何名字

Feature分支(有时被称为topic分支),用于为即将到来的或远期的版本开发新功能。当开始开发一个新的功能时,此时包含该功能的目标可能尚未很好定义。Feature分支的本质是,在新功能开发期间始终存在;但是它最终要合并回develop分支(将添加到下次发布的版本中)或者废弃(在实验让人沮丧的情况下)。

典型情况下,feature分支只存在于开发者的仓库中,而不在origin中出现。

创建feature分支

当开始工作于一个新功能时,从develop分支创建新的分支:

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

将完成的feature并入develop

完成的特性将会合并回develop分支,并终会被加入将到来的release中:

$ 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-forward的条件下,合并操作也总是生成一个commit对象。这可以避免feature分支中历史信息的丢失,并可使feature分支中的所有commit保持仍在一块。比较:

在后一种情况下,从Git的历史中是不可能看出,哪些commit对象共同实现了一个特性——你必须手动阅读所有的日志信息。而要移除整个特性(即,一组commit),在后一种情况下真真切切地让人头痛;而若使用了--no-ff标记,则很容易做到。

当然,这会创建一些空的commit对象,但收益比这点浪费要大得多。

不幸的是,我尚未找到使得git merge中默认行为启用--no-ff的方法,但它真的很需要如此。

发布分支(Release branches)

可能起源于分支:develop

必须合并回分支:develop 和 master

分支命名惯例:release-*

Release分支用于做新产品发布前的准备。它使得在最后一刻可以进行细枝末节的完善。更进一步讲,它允许小bug的修复以及发布所需元数据(版本号,构建日期等)的准备。通过在release分支做这些工作,develop分支可以干净地接收为下一个大发行版准备的功能。

从develop创建release分支的关键时机是,develop分支(几乎)可以反映新版本就绪状态的时刻。至少是将要建构的发行版所有的feature分支都已经被合并到了develop分支的时刻。所有的针对未来版本开发的feature可能不会被并入——它们必须等到该release分支创建以后。

正是在release分支开始时,即将发布的产品才被分配一个版本号——而不是先前。直到这一刻,develop分支才开始反映“下一版”的变化,但是在下一个release分支开始前,下一版最终将变成0.3还是1.0都是不明确的。这种决定是在release分支开始时,通过项目的版本号规则实施的。

创建发布分支

Release分支是从develop分支中创建而来。例如,假定1.1.5是当前产品的版本,而我们即将有一个大的发行版。Develop分支对于“下一版”已经就绪,而且我们已经确定这将是版本1.2(而不是1.1.6或2.0)。因此,我们创建release分支并赋予它一个反映新版本号的名字:

$ 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,并去等待下一个大的发行版本。

完成发布分支

当release分支的状态已经符合正式发行的要求时,一些动作需要被实施。首先,release分支被合并进master(回想一下,按定义,master上的每一个提交都导致一个新的版本)。其次,master上的该次提交必须被打上标签,以方便以后引用这个历史版本。最后,release分支中的所有变更都需要合并回develop,使得未来版本也包含这些bug补丁。

在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

release现在已经完成,且打上标签以备未来引用。

注: 你可能也想使用 -s 或 -u <key> 标记来私密签名。

要保持我们在release分支所做的变更,我们需要将其合并会develop。在Git中:

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

这步操作可能引起合并冲突(很可能,因为我们已经改变了版本号)。如果是这样,修复并提交。

现在,我们真的完成了,且该release分支将被移除,因为我们不再需要它了:

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

快速修复分支(Hotfix branches)

可能起源于分支:master

必须合并回分支:develop 和 master

分支命名惯例:hotfix-*

Hotfix分支非常像release分支,因为它也是为新产品(虽然是计划外的)发布做准备的。它们起源于对当前已发布产品中不理想状态的立即响应的需求。当产品中出现一个紧急bug需要被立即解决时,一个hotfix分支可以从master分支中标记该产品版本的标签开始创建。

其实质是,当一个人在准备产品的快速修复时,团队其他成员在develop分支的工作能够继续进行。

创建hotfix分支

Hotfix分支从master分支中创建。例如,假定1.2是当前已经发布的产品,却由于严重的bug导致了问题。但是develop分支中的变更尚不稳定。我们可能选择创建hotfix分支并开始修复这个问题:

$ 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并将代码以一个或多个commit的形式提交。

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

结束hotfix分支

当完成时,对bug的修复需要合并进master分支,也需要合并回develop分支,以确保补丁代码也被包含在下一个版本中。这与release分支结束时的情况是完全类似的。

首先,更新master并对该次发布打上标签。

$ 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中也包含该修复代码:

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

此处规则的一个例外是,当release分支已经存在,hotfix的变更需要合并进这个release分支,而不是develop。合并进release分支的补丁代码最终也会在release分支完成时被合并进develop。(如果develop中的工作急需这个补丁且等不及release最终完成,你也可以安全地将补丁合并进develop。)

最后,移除这个临时分支:

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

小结

虽然这个分支模型没有什么令人震惊的新东西,本文一开始给出的“大图片”在我们的项目中被证明了非常有用。它形成了一个优雅的很容易理解的模式,并强化团队成员对分支和发布过程的共享的理解。

转自:http://blog.csdn.net/passionboyxie/article/details/6820685

---恢复内容结束---

时间: 2024-12-30 00:05:44

【转】一个成功的Git分支模型 .的相关文章

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

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

一个成功的 Git 分支模型

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

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

在这篇文章中,我将推广一下大约一年前我介绍过的一些项目(公私皆有)中使用的开发模型,它们的结果都非常成功.有段时间我非常想写出来分享一下,但是我至今才抽出时间来.我不会言及任何项目细节,仅讨论分支策略和发布管理. 为何使用 git? 关于 Git 和集中式源码版本控制系统的优缺点对比讨论, 见 此 web.这里有很多精彩激烈的论战.作为一名开发者,现在我更偏好使用 Git .Git 真的改变了开发者关于合并和分支的认知.我来自传统的 CVS/Subversion 世界,合并/分支是件恐怖的事情

介绍一个成功的 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环境下