翻译自:https://nvie.com/posts/a-successful-git-branching-model/

在这篇文章中,主要介绍 Git 分支模型。不会谈论任何项目的细节,只讨论分支策略和发布管理。

Git分布式和集中式理解

我们配置了中央存储库可以很完美的配合该分支模型工作。这里需要注意下,这个仓库只是被认为 是中央仓库(因为Git是DVCS(分布式版本管理系统),在技术层面上没有中央仓库)。我们将这个中央仓库称为origin,应该所有Git用户都熟悉这个名称。

每个开发人员都会从中央库 pull 并 push origin。但除了集中式pull push 关系之外,每个开发人员还可以从其他开发人员的库中获取更改以形成子团队。例如,在将正在开发的代码push origin 之前,获取到其他开发人员的代码。这对于与一个大的新功能上的两个或更多开发人员一起工作可能是有用的 。在上图中,有alice和bob,alice和david以及clair和david的子团队。

从技术上讲,这意味着Alice已经定义了一个Git遥控器,名为bob,指向Bob的存储库,反之亦然。

主要分支

在核心,开发模型受到现有模型的极大启发。中央仓库拥有两个主要分支,具有无限的生命周期:

  • master
  • develop

master分支在origin应该存在于每一个用户的Git。另一个与master并行的分支是develop

我们认为origin/master是主要分支,这个分支HEAD源码始终反映生产就绪状态 ,简单来说就是master分支上的代码与生产使用的代码始终保持一致。这样有个好处就是,当生产代码出现紧急bug的时候,可以快速从master上fork出一个hotfix分支用来修复bug并发布,而不会因为修复线上bug,影响正在开发过程中的下一个版本的代码

我们认为origin/develop是主要开发分支,其HEAD源码始终反映了下一版本中最新交付的开发更改的状态。有些人称之为“整合分支”。这是可以用来建立夜间自动构建的分支。如果我们对此非常严格的执行,从理论上讲,我们可以使用Git钩子脚本在每次提交时自动构建和推出我们的项目到我们的测试服务器。

develop分支中的源代码到达稳定点并准备好发布时,所有更改都应以某种方式合并到master ,然后使用版本号进行标记。如何执行后面将详细讨论。

因此,每次将更改合并回master时,根据我们的定义,这就是一个新的生产版本。

支持分支

接下来除了两个主分支masterdevelop,我们的开发模型使用各种支持分支来帮助团队成员之间的并行开发,轻松跟踪功能,准备生产版本以及帮助快速修复实时生产问题。与主分支不同,这些分支的寿命有限,因为它们最终会被删除。

我们使用的不同类型的分支分别是:

  • 功能分支             命名方式:feature-*
  • 发布分支             命名方式:release-*
  • 修补bug分支       命名方式:hotfix-*

这些分支中每一个都有特定的目的,并且有着严格的规则:从哪些分支中fork出来,又合并到那些分支中。

分支类型根据我们如何使用它们进行分类。

功能分支

分支出自:develop

必须合并回:develop

分支命名约定:最好是 feature-[功能名],当然如果是想自己定义其他名字只要不是masterdeveloprelease-*, or 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参数使合并始终创建新的commit,最新版中git merge 默认的就是--no-ff。这样可以避免丢失功能分支的历史信息,并将所有添加功能的 commit 组合到一个commit中。对比:

在后一种情况下,不可能从Git历史中看到哪些 commit 实现了一个功能 - 您必须手动读取所有日志消息。恢复整个功能(即一组提交)在后一种情况下也是比较头痛的,而如果使用该--no-ff标志则很容易完成 。

虽然它会创建一些(空的)commit,但增益远远大于成本。

发布分支

分支出自:develop

必须合并回:develop 和 master

分支命名约定:release-[版本号]

发布分支主要用来发布新的版本到生产。它可以用来修复最后一分钟的bug,当在发布的过程中发现了新的bug,可以直接在release分支中修改。develop 分支将接收下一个大版本的功能。

需要注意的是在develop上创建一个新的发布分支的时候,develop分支的代码应该是测试完毕后准备发布的代码,至少下一个版本所有的功能都已经合并到develop分支 。

当新建了发布分支分配新的版本号,从这个时候开始develop分支反映的将应该是下一个版本的代码。比如新建了release-1.6 后 1.6版本的代码将不再允许提交到develop分支中。

创建发布分支

发布分支是从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
files changed, insertions(+), deletions(-)

创建新分支并切换到它后,我们会更新版本号。这  bump-version.sh是一个虚构的shell脚本,它可以更改工作副本中的某些文件以反映新版本。(这当然可以是手动更改 - 关键是某些文件会发生变化。)然后提交了最新的版本号。

这个新分支可能存在一段时间,直到新版发布。在此期间,可以在此分支中修复bug(而不是在develop分支上)。严禁在此处添加大型新功能,新功能必须合并到develop等待下一个大版本。

完成发布分支

当release分支准备好真正发布的时候,需要执行一些操作。首先,release分支合并到 master(因为每次提交master都是按照定义的新版本)。接下来,master必须标记 (tag) 该提交,以便将来参考此历史版本。最后,需要将发布分支上的更改合并回来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>标记以加密方式对您的标记进行签名。

为了保持release分支中所做的更改,我们需要将这些更改合并到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 分支主要用来修复生产的紧急bug,比如当开发人员正在 feature、develop 分支 开发下一个版本的功能,而生产出现了紧急bug 必须立刻修复并发布。而你又不想把当前未完成的版本发布到生产,这个时候我们可以在 master 分支上 fork 一个新的 hotfix 分支用来修复bug

,这样的话就不会影响到下一个版本的开发。

创建修补 Bug 分支

master分支创建修复 bug 分支。例如,假设版本1.2是当前生产版本正在运行并且由于严重错误而影响生产正常使用。但是develop分支代码仍然不稳定。然后我们可以 fork hotfix分支并开始修复问题:

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

新建分支后不要忘记标记小版本号!

然后,修复 bug 并提交一个或多个单独 commit。

$ git commit -m "Fixed severe production problem"
[hotfix-1.2. abbe5d6] Fixed severe production problem
files changed, insertions(+), deletions(-)

完成修补 Bug 分支

完成后,需要将hotfix分支合并回master,同时也需要合并回develop,以保证修复bug的代码也包含在下一个版本中。这与发布分支的完成方式相似。

首先,更新master并标记版本。

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

编辑:您还可以使用-s-u <key>标记以加密方式对您的标记进行签名。

接下来,合并hotfix 到 develop

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

此处有一个例外就是, 当前release分支存在时,只需要将hotfix分支合并到该release分支中即可,而不是develop。将hotfix分支合并到release分支中,修复的代码最终也会在release分支完成时被合并到develop。(当然如果develop立刻需要此修复bug代码,不能等到release分支完成,您也可以直接地将hotfix合并到develop。)

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

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

Git 分支模型的更多相关文章

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

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

  2. 成熟的 Git 分支模型

    个人博客原文: 成熟的 Git 分支模型 今天介绍一下工作中会用到的 Git 分支模型. 先贴上图以表敬意 闲言 在学校不管是自己写课程设计还是给老师做项目,有 2 到 3 个人一起协作开发时就会使用 ...

  3. 项目开发中git常用命令、git工作流、git分支模型

    #新建代码库git init # 在当前目录新建一个Git代码库git init [project-name] # 新建一个目录,将其初始化为Git代码库git clone [url] # 下载一个项 ...

  4. 近期关于CI/CD策略以及git分支模型的思考

    近两个月由于个人处于新环境.新项目的适应阶段,没怎么提笔写些文章.中间有好几个想法想记录下来分享,但受限于没有很好的时间段供自己总结思考(也可以总结为间歇性懒癌和剧癌发作),便啥也没有更新.借这个周末 ...

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

    英文原文: http://nvie.com/posts/a-successful-git-branching-model/ 中文版: 在这篇文章中,我提出一个开发模型.我已经将这个开发模型引入到我所有 ...

  6. 一个成功的Git分支模型

    原文: http://www.juvenxu.com/2010/11/28/a-successful-git-branching-model/ 本文中我会展示一种开发模型,一年前该模型就已经被我用在所 ...

  7. 一个成功的 Git 分支模型

    在这篇文章中介绍的开发模型在大约一年前已经在我的私有项目和工作引入的,而且已经被证明是非常成功的.我想写一些关于这个模型的东西已经好一段时间了,但是一直苦于没有时间,不过现在可以了.我不想探讨任何项目 ...

  8. Git分支模型

    转自:http://www.cnblogs.com/byeyear/archive/2012/11/28/2793374.html 本文介绍一种使用Git进行源代码管理的分支模型,着重于如何使用Git ...

  9. Git 分支模型与开发规范

    GitHub Flow & Git Flow 基于Git 的两种协作开发模式 01.分支模型 master:长期分支,一般用于管理对外发布版本,每个 commit 对一个 tag,也就是一个发 ...

随机推荐

  1. js基础--浏览器标签页隐藏或显示状态 visibility详解

    欢迎访问我的个人博客:http://www.xiaolongwu.cn 前言 在工作中我们可能会遇到这样的需求,当浏览器切换到别的标签页或着最小化时,我们需要暂停页面上正在播放的视频或者音乐,这个需求 ...

  2. sh 脚本执行sql文件传参数

    一.前言 今天做数据删除,用的命令行输入参数,并且调用执行的sql文件,我采用了sed命令,进行替换. sh脚本如下 #! /bin/sh echo "Please enter the ba ...

  3. Js的String对象

    Js的String对象常用方法: 方法一.得到某字符在字符串中的索引位置. str.indexOf(findStr,[index])--返回的是要查找字符在字符串中的位置索引   ,index开始查找 ...

  4. PAT1083:List Grades

    1083. List Grades (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Given a l ...

  5. Linux kernel的中断子系统之(二):IRQ Domain介绍

    返回目录:<ARM-Linux中断系统>. 总结:一.二概述了软硬件不同角度的IRQ Number和HW Interrupt ID,这就需要他们之间架个桥梁. 三介绍了架设这种桥梁的几种方 ...

  6. 写个批处理脚本来帮忙干活--遍历文件夹&字符串处理

    这次打算写几篇关于脚本方面的博客,主要是记录一下 Gradle 脚本和批处理脚本的一些写法,方便后续查阅. 前言 平常开发过程中,一些较为重复的手工性工作,如果能让脚本来帮忙处理,自然是最好的,刚好之 ...

  7. Ribbon负载均衡策略配置

    在这里吐槽一句:网上很多文章真是神坑,你不看还好,看了只会问题越来越多,就连之前的问题都没有解决!!! 不多说了,Ribbon作为后端负载均衡器,比Nginx更注重的是请求分发而不是承担并发,可以直接 ...

  8. Spring Boot工程支持HTTP和HTTPS,HTTP重定向HTTPS

    本文试图以通俗易通的方式介绍Https的工作原理,不纠结具体的术语,不考证严格的流程.我相信弄懂了原理之后,到了具体操作和实现的时候,方向就不会错,然后条条大路通罗马.阅读文本需要提前大致了解对称加密 ...

  9. c# Socket通信异步TCP

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...

  10. 【转】linux系统中如何进入退出vim编辑器,方法及区别

    在linux家族中,vim编辑器是系统自带的文本编辑器,其功能强大自不必说了. 偶有小白,刚接触linux,要修改某个文本文件,不可能像WINDOWS那样操作,更有甚者,进入VI编辑器后,无法退出以致 ...