一个成功的Git分支模型

原文链接 : http://nvie.com/posts/a-successful-git-branching-model/

在这篇文章中,我将要介绍版本的发展模式,在过去的一年中我已经介绍了一些我的工程(无论是私有还有工作的),那些已经被证明是非常成功的。我已经打算写这篇很久了。但是一直到最近我都没有找到时间彻底的去做这件事。我不会过多的去讨论工程的细节问题,几乎都是关于分支策略和版本管理

这是Git的一个汇总,作为一个管理我们所有源代码版本的工具。

为什么要选择git

对于彻底的讨论支持或者反对Git同其他版本控制工具相比,曾经有一场激烈的争论,作为一个开发者,我更倾向于选择Git超过其他现在所有的工具。Git已经改变了开发者对分支和融合的概念了。从经典的CVS/Subversion中,融合/分支经常被认为是小心翼翼的()仅仅是你只做了一点点事情。

但是对于Git,尽管这些工作是很简单很廉价的,但是他们被认为是组成我们每天的核心工作,真的,举个例子来说,在CVS/subversion,分支和融合将会在后面的章节讨论(对于有经验的用户),然后,在每天的Git日志中,他们已经被涵盖在前三章了。

由于其简单性和重复性,分支和融合不在是令人害怕的了。版本控制工具已经比其他东西更支持分支和融合了。

分散而集中

我们通过设置知识库来建立我们的分支模型,就是那个中间的有“truth”的知识库。注意只有这个知识库被认为是核心,我们将他看做是原始的。这个名字和Git的使用者很相似

每一个开发者向origin推送,但是除了和核心的origin有关系,开发者也可以改变其他同辈的子队伍的形式。比如,这在工作中可能非常常见对于两个工作在一起的人在一个大的新的特性中

在技术上说,这意味着Alice远程定义了一个Git,名字叫做bob,指向Bob的知识库,反之亦然

 

主分支

在核心库中,模式的发展受到现有的模式很大的启发,主要的部分有两个生命周期无限时间的分支:

·        master(主分支)

·        develop(开发分支)

 

每一个git的使用者都应该很熟悉master(主分支),和主分支相平行的是发展分支

我们认为原始分支(origin)/主分支(master)是核心代码的主要部分,反应的是代码就绪状态

 

我们认为原始分支(origin)/开发分支(develop)是核心代码中反应的是最近交付的代码对于下一个版本的变化,有一些人也叫他们“集成分支“,每天自动构建的代码就是从这里发布的。

当核心代码在develop分支中达到一个稳定点并且准备好被发布的时候,所有的改变都要被合并到master中,并且被打上一个版本号,至于是怎么做的,具体的细节会在下面讨论到。

因此,每当向主分支中合并其他的改变时,这些都会被明显的发现是一个新的版本,我们通常会很严格的对待这一切,理论上说,我们可以使用一个git的钩子脚本自动的完成,master的一个主要任务就是时刻关注发布的我们的软件产品有什么服务

 

支持分支(Supporting branches)

 

在主分支的master和decelop之后,我们的开发模式使用了多种多样的支持分支来帮助并行开发,例如在团队成员和轻松跟踪,准备为新版本的发布,或者帮助快速修复产品中的问题,这些分支通常都有生命周期的限制,他们最后会被删除。

我们可能会用到的不同类型的分支主要有:

·        Feature(特性分支)

·        Release(发布分支)

·        Hotfix(热修复分支)

 

每一种分支都有一个特别的目的,并且被严格限制在他们所在的主分支和他们将要被合并去的目标中,下面我们花几分钟的时间具体讲一下他们

不管怎么样,这些“特殊”分支都来源于同一个技术观点,这些分支的类型都是在我们如何使用他们时分类的,他们当然会平稳的回到老的git分支中。

 

特性分支(Feature):

可以从哪个分支分出来:

develop

必须回到哪个分支去:

develop

分支命名习惯:

除了master,develop。release-*,或者hotfix-*以外的名字

特性分支(也有人叫他们主题分支)通常被用来为下个版本开发新的特性或者未来的版本,当开始开发一个特性时,这个特性要合并到哪个目标版本中在当时可能还是不知道的。特性分支的本质是只要在开发版本中存在特性,最后都会回到develop分支中(成功的向接下来的版本中添加了新特性),或者丢弃(如果是一个令人失望的实验)。

特性分支只存在于开发者中,并不在origin中,

创建一个特性分支:

当开始产生一个新特性的时候,从develop分支创建一个新的分支:

$git checkout -b myfeature develop (转移到一个新的分支,名字叫做“myfeature”)

向develop中完成合并一个分支

$git checkout develop (转到‘develop’分支中)

$git merge --no-ff myfeature(更新,总结改变)

$git branch -d myfeature(删除myfeature分支)

$git push orgin develop

--no-ff命令合并时总是会创建一个新的承担对象,即使这个合并可能会引起快速进展。这个可以避免丢失历史已经存在的特性信息,并且所有组都可以一起加入新的特性

在上一个例子中,很难在git的历史版本中发现交付新的特性,你可以手工阅读信息日志,然后回到整个特性中,后面这个例子就是一个很令人头疼的例子,然而当使用--no-ff选项的时候,这一切就会很容易被做好了。

所以,创建一个简单的空对象来实现这一切,收货比付出要大的多了

发布分支(Release):

可以从哪个分支分出来:

develop

必须回到哪个分支去:

develop和master

分支命名习惯:

release-*

发布分支支持为一个新发布的产品做准备,他们允许最后时刻提交代码。然后,他允许少量的错误修复和准备下一个版本的元数据(版本号,创建日期等)。release分支通过做所有的这些事情,develop分支可以很清楚的获得下一个大版本的特性变化。

对于一个分支最重要的时刻是要从一个新的develop分支中什么时候反应下一个新版本。至少所有的特性的目标都是将要创建的release必须要在什么时间点及时的合并到develop,所有的feature目标在未来版本可以不必一直等到发布分支的发布。

这确实需要在一开始就指派版本号,但是不用过早。一直到,develop分支反应出需要“下一个版本”的时候,但是,我们并不知道下一个版本究竟是0.3还是1.0,直到发布分支出现,这个决定由发布分支自己项目规定来决定版本号

创建一个release分支

release分支由develop分支产生,举个例子,我们说版本1.1.5是当前产品版本,我们在接下来将会有一个更大的版本,这个阶段的develop已经可以叫做“下一个版本”了,并且我们已经决定下一个版本是1.2(不是1.16或者2.0)。所以我们的分支反应的是新版本的版本号

$git checkout -b ralease-1.2 develop(转到一个新的分支“release-1.2”)

$./bump-version.sh 1.2(文件准备成功,版本升级到1.2)

$git commit -a -m "Bumped versionnumber to 1.2"

创建新的分支并且转到他的之后,我们会命名版本号,这里,bump-version.sh是一个虚构的脚本,他能够修改副本中的一些文件以及反映新版本特性,然后这个版本就成功了。

这个新的分支可以存在一定时间,直到清楚的发布新版本。在此期间,可以在分支中应用错误修复(并不是在develop中),但是不许增加新特性,他们必须合并到develop分支中,因此,等到下一个大的版本发布

结束一个release分支

当一个release版本准备变成一个新的发布版本的时候,有一些工作需要被处理。首先,发布分支必须要合并到master中(要记住,因为每一个master上的任务都要清楚的发布),接下来,已经提交的master必须被标记为很容易在未来参考的历史版本。最后,在发布版本中的改变必须要被合并到develop中,所以,未来的release版本也必须包含错误的修复功能。

首先Git的步骤:

$git checkout master(转到master分支)

$git merge --np-ff release-1.2(递归的合并回去)

$git tag -a 1.2

这样发布就完成了,并且为未来的参考做了标记

为了保证这些改变在发布分支中,我们需要将他们合并到develop中。

$git checkout develop

$git merge --no-ff release-1.2

这个步骤有可能引起合并冲突(由于我们改变了版本号),如果这样,修复之后再提交

现在,我们是真的完成了发布分支,然后可以删除他了,因为不在需要他了

$git branch -d release-1.2

特性分支(Feature):

可以从哪个分支分出来:

master

必须回到哪个分支去:

develop 和 master

分支命名习惯:

hotfix-*



热修复分支非常像发布分支,在这里,他们也准备发布新的产品,他们必须立刻的一个没想到的阶段正在使用的版本做修复。当一个产品出现关键的错误必须被立刻解决时,热修复分支必须从主分支中标记产品版本的相应的标签。

热修复补丁的本质是当有一个人准备快速修复产品的时候,团队其他成员可以继续。

创建一个热修复补丁

热修复补丁从主分支中创建,例如,我们说当前正在运行的产品是1.2版本引起了一个大的麻烦,由于一些bug。但是,develop分支中并不稳定,我们可以创建一个热修复补丁,开始修复这个问题

$git checkout -b hotfix-1.2.1 master(转到一个新的分支“hotfix-1.2.1”)

$./bump-version.sh 1.2.1(文件准本成功。版本升级到1.2.1)

$git commit -a -m"Bumped versionnumber to 1.2.1"(1个文件改变,1个加入,1个删除)

不要忘了升级版本号之后的事情

然后,修复bug的任务可以交给一个或者多个任务中

$git commit -m "Fix severe productionproblem"

(5个文件被改变,32个加入,17个删除)

结束热修复分支

当我们结束时,修复错误需要合并回master中,并且需要合并到develop中,为了保护在下一个版本中错误也被修复,这个和发布版本的结束时是相同的

首先,更新一个master,然后标记发布版本

$git checkout master(转到master)

$git merge --no-ff hotfix-1.2.1(递归合并)

$git tag -a 1.2.1(总结改变)

接下来,包括错误修改回develop

$git checkout develop(转到develop分支)

$git merge --no-ff hotfix-1.2.1(递归合并,总结改变)

这里有一个需要注意的规则,当一个发布分支已经存在的时候,热修复改变需要回到发布分支,而不是develop分支,向后合并的错误修复到发布分支,当发布分支结束以后,最后也会使错误修复回到develop中。(如果在develop分支中立刻修复错误,而不是等待发布分支结束,你可以很安全的修复bug到develop已经存在的版本中)

最后,删除当前的分支

$git branch -d hotfix-1.2.1(删除热修复分支1.2.1)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值