Git 工做流,知其然知其因此然

阅读原文:github.com/ruizhengyun…html

前言

虽然经历过 svn 年代,工做流程中也用到了 svn,但更多时候仍是在用 git,相信不少开发小伙伴也在用 git 吧,市场上已经有不少关于 git 知识介绍了,那为何我还要写一本线上小书呢?坦白说写下来是为了手过把瘾、这个过程对 git 知识也有了个系统性认知,若是能帮到读者一二,那最好不过了。git

和别的小书稍稍有个出入,不在给 Git 给予太多文字的简介,由于你确定多少知道它是什么东西。github

为何有分支

其实很简单,就是来源功能驱动开发(Feature-driven developer,简称 FDD),协做开发就得有版本管理,管理的天然就是分支了。编程

功能驱动开发就是:需求来了,如果功能,则创建功能分支(feature branch);如果 bug,则创建补丁分支(hotfix branch)。完成开发后,该分支就合并到相应主分支,而后删除,版本发布后记得打上 git 标签。svn

工做流

Git 做为一个源码管理系统,多人协做才能看到其价值。这和 github 社会化编程相互辉映,成就彼此。既然协做,就得有一个规范化的工做流程,让你们有效地合做,使得项目层次分明地发展下去。工做流程能够称为 "workflow" 或"flow",即水流,比喻项目像水流那样,顺畅、天然地向前流动。工具

对于工做流程方式,经常使用 3 种方式测试

  • Git flow
  • Github flow
  • Gitlab flow

Git flow

这个工做流是 Vincent Driessen 2010 年发布出来的分支管理模型,热度很是高,我安利的也是这个,公司管理项目也是这么玩的。优化

  • 按功能划分,可分为 5 种分支Master、Develop、Release、Feature 和 Hotfix
  • 按生命周期划分,可分为长期分支和暂时分支,更贴切地说,主要分支和协助分支;
分支 分支名称 生命周期 描述
Master 主分支 长期 从这个分支上检出的都是稳定的发布版,版本发布后记得打上 git 标签。好处是,在测试的时候,不影响下一个版本功能并行开发
Hotfix 修复分支 暂时 用于线上紧急 bug 修复,修复后,合并回 Master 和 Develop,而后删除分支
Release 预发分支 暂时 版本提测后,删除 Feature,发现 bug,从 Develop 检出 Release 分支,修改后提交,测试发布后,合并到 Master 和 Develop,而后删除分支
Develop 开发分支 长期 用于平常开发,存放最新的开发版,完成一个版本合并到这里
Feature 功能分支 暂时 用来作分模块功能开发,本次版本有 5 我的开发就建 5 个分支,完成后合并到 Develop

总结下ui

  • Master 检出 Hotfix、Develop 分支,合并 Hotfix、Release 分支,而后打标签;
  • Develop 检出 Feature、Release 分支,合并 Feature、Release、Master 分支;
  • 被合并的分支删可当即除掉;

Merge

即合并分支,这个阶段加上参数 no-ff,即策略合并,这这种方式会多以合并提交,好处是保证一个很是清楚的提交历史,能够看到被合并分支的存在,我想这也是分支存在的一块儿所在。相反,不要选择默认合并方式 Fast-Forwordspa

怎么样,上面流程配色是否很舒服和分支流向是否很清晰?

完美背后的瑕疵

虽然 Git Flow 解决了项目管理的分支管理,但实际使用过程当中,仍是有一些问题:

  • Hotfix 和 Release 分支在版本快速迭代的项目中,几乎用不到,刚开发完就直接合并到 Master 发版,出现问题 Develop 分支直接修复发布下个版本了;
  • Hotfix 从 Master 检出,完成后合并到 Master 分支,Release 分支 Develop 检出,完成后合并到 Master 分支和 Develop 分支,实际项目管理中,不少开发者会忘记合并回 Master 分支和 Develop 分支;

Github flow

最简单的一种工做流程方式,开源项目就是采用这种方式,含Master + Feature(含 Hotfix)

  • Master 主分支
  • Feature 功能分支(Hotfix 补丁分支,补丁也能够看作功能)

说明

  • Master 是惟一分支,永远是可发布状态。通常主分支都设置 protected 分支保护,只有有权限的人才能推送代码到 Master;
  • 如有新功能(补丁也是一种功能),从 Master 检出新分支;
  • 本地分支提交代码,保证按时向远程仓库推送;
  • 功能开发完毕,能够发起一个 pull request(PR),PR 既是一个通知,让别人注意到你的请求,也是一种对话机制,社会开发人员一块儿评审和讨论你的代码,这个过程当中可继续提交代码;
  • 当 review 或者讨论经过后,代码会合并到目标分支;
  • 一旦合并到 Master,应该当即发布,从新部署后,你检出的分支就被删除;

最大特点

在我看来,Github flow 最大特点就是 PR,这是一个伟大的发明,除了分支合并功能,还有

  • 能够很好控制分支合并权限;
  • 分支不是你想合并就合并,须要对方赞成;
  • 对于"持续发布"的产品,再合适不过;
  • 问题讨论或寻求其余小伙伴们的帮助,就和拉个群差很少,能够选择相关的人参与,并且参与的人还能够向你的分支提交代码,能够说,是很是适合社会化编程代码交流。
  • 代码 Review,若是代码写的不友好,有了 pull request 提供的评论功能支持,能够接受 review 的实时吐槽;

问题追踪

平常开发中,会用到第三方库。使用过程当中,出现了问题,第一个反应是去这个第三方库的 GitHub 仓库去搜索一下 issue ,看没有人遇到过,项目维护者修复了没有,通常未解决的 issue 是 open 状态,已解决的会被标记为 closed。这就是问题追踪 issue tracking(issue 解决效率也是选用第三方库的一个标准)。

若是你第三方库(开源项目)的维护者,除了标记 issue 的状态(open 和 closed),还能够给它标记上不一样的标签,来优化项目。当提交的时候,若是提交信息中有 fix #1 等字段,能够自动关闭对应编号的 issue。

不得不说问题追踪很是适合开源项目。Github 社区使用的就是这个工做流模型,能够建个项目耍耍,拉进直男间的距离,哈哈。

完美背后的瑕疵

GitHub Flow 是简化了 Git Flow,就一个长期分支 Master,同时提供了图形界面工具,必定程度上避免了一些问题,但仍是有一些实际问题:

  • 版本的延迟发布(例如 iOS 应用审核到经过中间,此时要往 Master 上推送代码);
  • 不一样环境的部署;
  • 不一样版本发布与修复,一个 Master 分支不够用啊(臣妾作不到啊);

Gitlab flow

年轻的工做流模式。它是 GitLab 的 CEO Sytse Sijbrandij 在 2014 年 9月 29 正式发布出来的。由于后出现的,因此站在巨人的肩膀上,集两种方式之长,补其之短。既有适应不一样开发环境的弹性(分支策略),又有单一主分支的简单和便利(PR 和 issue tracking)。

版本的延迟发布

一个 Master 分支不够,那就添加了一个分支 Prodution,专门用来发布版本。

不一样环境的部署及上游优先

在 Master 分支以外,再建两个环境分支:

分支 环境分支 上下游
Master 开发分支 功能分支是开发分支的"上游"
Pre-production 预发分支 开发分支是预发分支的"上游"
Production 生产分支 预发分支又是生产分支的"上游"
Feature -> Master -> Pre-production -> Production
复制代码

若代码的变化,必须由"上游"向"下游"发展,即合并顺序,按环境依次推送,确保代码测试过,从上游分支合并到下游分支。紧急状况下,才容许跳过上游,直接合并到下游分支,即 upstream first,上游优先。

版本发布分支

对外发布版本的记录是很是重要的。线上出现了一个问题,须要拿到问题出现对应版本的代码,才能准肯定位问题。在 Git Flow,版本记录是经过 Master 上的 Tag 来记录。发现问题,建立 Hotfix 分支,完成以后合并到 Master 和 Develop。

在 GitLab Flow ,建议的作法是每个稳定版本,都要从 Master 分支拉出一个分支,好比 0-1-0-stable、0-2-0-stable 等等。发现问题,就从对应版本分支建立修复分支,完成以后,先合并到 Master。若此时还有预发布分支,还要合并到 Release 分支,遵循 “上游优先” 原则。

技巧

Pull Request

功能分支合并进 Master 分支,必须经过 Pull Request(Gitlab 是 Merge Request)。PR 本质是一种对话机制,提交的时候,@相关人员或团队,引发他们的注意。

Protected branch

Master 分支应该受到保护,不是每一个人均可以修改这个分支,以及拥有审批 PR 的权力。Github 和 Gitlab 都提供"保护分支"(Protected branch)这个功能。

Merge

文中提了 Git 有两种合并方式

  • 直进式合并 fast forward,不生成单独的合并节点,不利于保持 commit 信息的清晰,也不利于之后的回滚;
  • 非直进式合并 none fast-forword,会生成单独节点,记得合并时加上 --no-ff 参数;

参考

相关文章
相关标签/搜索