GitHub Flow

来源:互联网 发布:今年好听的网络歌曲 编辑:程序博客网 时间:2024/05/01 22:03

原文地址http://scottchacon.com/2011/08/31/github-flow.html

git-flow的问题

    我环游各地教人们Git,而最近,我教的几乎每个班级和工作室都在问我对于git-flow的看法。我的回答总是觉得这个东西非常伟大——它采用了一个有着无数工作流程和记录了良好测试的系统(Git),这个系统拥有的灵活工作流程对许多开发者而言是非常清晰直观的方式。它已经变成了一种标准,让开发者能够在项目和公司间灵活应对并熟悉这个标准化的流程。

    但是它也有它的问题。我已经听到一批条人的大堆观点,嫌新特性以“develop”开始而不是“master”,又或它处理程序修补的方式,但是这些观点真的非常幼稚。

    对我而言更大的问题是,这个东西比大多数开发者和开发团队的需求更加复杂。复杂到需要开发一个巨大的帮助脚本来执行flow的理念。虽然这个东西很酷,但问题是这个不能在Git的GUI层面解决,只能在命令行下, so the only people who have to learn the complex workflow really well, because they have to do all the steps manually, are the same people who aren’t comfortable with the system enough to use it from the command line. This can be a huge problem.(这段话太难翻译了。。。谁帮我翻译并回复一下,小弟感激不尽)

    这两个问题都可以通过一个更加简单的步骤轻松解决。在GitHub上,我们不使用git-flow。我们通常使用的是一个更加简单的Git workflow。

    它的简洁给了它许多优势。其中一个就是对人们来说它很容易理解,意味着人们可以很快掌握它而且他们很少如果曾经把事情搞砸或者不得不undo他们搞错的步骤。另外一个是我们不需要一个包装脚本来帮助执行或者遵守它,所以使用GUI神马的都不是问题亲~

GitHub Flow

    那么,为什么我们在GitHub上使用git-flow呢?主要的问题是我们老是在部署。git-flow的步骤被大量围绕“release”而设计。我们不是真的有“release”因为我们每天都会部署产品——一天好几次是经常的事情。我们能通过我们的聊天室机器人这样做,也是我们CI(译者:什么玩意儿?)结果被呈现的地方。我们试图让测试和shipping的过程越简单越好,这样每一个员工在做这些事情的时候感觉会舒适一些。

    频繁的部署有许多优势。如果你每隔几个小时部署一次,引入大量的bug是几乎不可能的事情。小的问题可能出现,但是它们能被很快干掉并重新部署。通常,你必须要做”hotfix“或者其他超出一般步骤的事情,但是这仅仅是我们一般步骤的一部分——在GitHub flow和hotfix与细小特性之间是没有差别的。

    另一个频繁部署的好处是迅速找到所有问题的根源。我们能非常快的为吸引我们注意或者实现了小但是有趣特性的请求而负安全问题,同时,我们能使用同样的方法来确定那些我们用来解决一般乃至大的特性开发而做的改变。都是一样一样的,一样一样的简单。

我们如何做到

    那么,什么是GitHub Flow呢?

    · 任何在“master”分支中的都是可部署的

    · 为了一些新的工作,创建“master”的分支,这些分支拥有描述性的命名(如:new-oauth2-scopes)

    · 当你需要反馈和帮助的时候,或者你觉得分支已经可以合并,打开一个pull request

    · 在有人看过并确认这些特性以后,你就能把它合并到主分支中

    · 一旦合并并push到‘master’,你就能或者应该马上部署

    这就是整个流程(flow)。非常简单,非常有效并且对于大的团队同样适用——GitHub现在有35个雇员,也许有大概15到20个人在同一时刻在同一个项目(github.com)上工作。我认为大多数同一时间工作在相同的逻辑代码,并产生冲突的开发团队或组织都是这个规模或者人数更少。尤其是那些激进到被快速且一直的开发。

    那么,就让我们依次来看看这些步骤。

    #1-任何在“master”分支中的都是可部署的

这是这个系统中唯一的硬性规定。唯一具有所有特征和一贯意义的分支是我们所命名的master。对我们而言,这意味着它已经被部署了或者最坏的情况是会在几个小时内被部署。倒带(分支往后回到先前的一次commit来还原工作)这种事情是极其少见的——如果有问题,commits会被还原,或者引入新的commits来修复这个问题,但是这个分支本身几乎永远不会回滚到从前。

master分支总是稳定的,从它部署或者创建一个新的分支总是安全可靠的。如果你push一些没有被测试的东西到master或者打破了一些建立,你便打破了开发团队的社会化契约而且你通常会感到糟糕。每一个我们push的分支都已经在跑的时候测试了并且在聊天室中报告了它,所以如果你还没有在本地跑它们,你可以简单的push到一个话题分支(甚至是一个只有一个commit的分支)到服务端并等着Jenkins来告诉你它是否通过所有事情。

你可以有一个只有当你部署的时候才会被更新的deployed分支,但是我不这样做。我们只是通过网页应用本身暴露当前部署的SHA,当我们需要对照的时候curl它。

    #2-创建“master”的拥有描述性命名的分支

当你希望开始工作,你创建一个描述性的命名分支在master分支之后。一些在GitHub代码库中的例子会使用user-content-cache-key,submodules-init-task或者redis2-transition.这样有好几个优势——一个是当你fetch的时候,你能看见其他人一直工作时的话题。另外一个是如果你一会儿废除了一个分支并之后回到了它,记住它是什么是一件很简单的事情。

这是很不错的,因为当你去GitHub的分支列表页面,我们能容易的知道哪个分支最近被工作过并大致的了解他们在上面做了多少工作。


这就像是一个即将更新的当前状态粗糙的特性列表。如果你没有正在使用这个页面,它是很棒的——它仅仅展现给你与你当前选择的分支有关联的拥有唯一工作的分支,并对它们排序,这样谁最近做了些什么便会出现在最上边。如果我真的很好奇,我可以点击‘Compare’按钮来看commits到底有什么不一样的。

那么,对于写的这个文章,我们的仓库中有44个分支而且是未合并的,但是我依然能看见它们中的9个或者10个已经在上周被push上去了。

    #3-频繁推到命名了的分支

git-flow的另外一个巨大的不一样的地方是我们频繁的push到被命名的分支到服务端。既然我们真正关心的事情是部署的角度上的master,pushing到服务端不会让任何人抓狂或者让它们困惑——每一件事不是master就是正在被开发的。

这个同样确保了我们的工作总是被备份了的以防电脑被偷或者硬件挂了。更重要的事情是,它让每个人都在频繁的交流。一个简单的‘git fetch’基本上会给你一个关于当前其他人进度的TODO list。

$ git fetchremote: Counting objects: 3032, done.remote: Compressing objects: 100% (947/947), done.remote: Total 2672 (delta 1993), reused 2328 (delta 1689)Receiving objects: 100% (2672/2672), 16.45 MiB | 1.04 MiB/s, done.Resolving deltas: 100% (1993/1993), completed with 213 local objects.From github.com:github/github * [new branch]      charlock-linguist -> origin/charlock-linguist * [new branch]      enterprise-non-config -> origin/enterprise-non-config * [new branch]      fi-signup  -> origin/fi-signup   2647a42..4d6d2c2  git-http-server -> origin/git-http-server * [new branch]      knyle-style-commits -> origin/knyle-style-commits   157d2b0..d33e00d  master     -> origin/master * [new branch]      menu-behavior-act-i -> origin/menu-behavior-act-i   ea1c5e2..dfd315a  no-inline-js-config -> origin/no-inline-js-config * [new branch]      svg-tests  -> origin/svg-tests   87bb870..9da23f3  view-modes -> origin/view-modes * [new branch]      wild-renaming -> origin/wild-renaming

  通过盯着 GitHub Branch List ,它让每个人都能看见,其他人正在做些什么这样就能检查它们并看它们是否需要一些帮助的样子。

    #4-在任何时候打开一个pull请求

GitHub有着一个非常神器的代码审查系统叫Pull Requests而且我恐怕很多人都不了解这个东西。许多人使用它来打开源码工作——fork一个项目、更新一个项目、想维护者发送一个pull请求。然而,这个同样可以容易的被用作一个内部的代码审查系统,也正是俺在做的。

事实上,我们更多的是把它用作分支对话视图而不是一个pull请求。你可以发送pull请从一个分支到另外一个独立的项目(公共的或者私有的)在GitHub上,如此你就能使用它们来说”劳资需要帮助哒或者帮忙看哈子“接着一句”请把它合并进来吧亲“。


这里你能看见Josh cc'ing Brian为了审核以及Brian带着一些关于这些代码的建议进来。再往下我们可以看见Josh承认了Brian关心的东西并推送了更多代码来定位它们。


最终你能看见的就是我们任然在试运营阶段——这还不是一个准备好部署的分支,我们使用Pull请求来审查代码在我们想部署合并到‘master’之前。

如果你卡在你的特性开发的分支进度上或是需要帮助和建议,又或如果你是一个开发者,需要一个设计师来审核你的工作(反之亦然),或者甚至如果你只有更少的代码、一些截图和大致的想法,你打开一个pull请求。你能在GitHub系统上cc人们通过@名字,这样如果你希望从特点的人那里得到审核与反馈,你就简单的这样做就可以了。


当你觉得一切都完成的差不多的时候可以到下一步了。

    #5-只在pull请求审批通过后合并

我们并不简单的直接在‘master'上工作或者在一个话题分支上并在我们觉得它完成的时候才会合并——我们试图得到来自公司里面他人的牵手。这个通常只是一个简单的emoji表情或者一个小评论,但是我们却尝试让其他人来看一看。


一旦我们达成,分支通过了CI,我们就能合并到主分支并部署了,同时也会在我们推送以后自动的关闭到pull请求。

    #6-在审核之后马上部署

最终,你的工作被完成了并被合并到 'master'分支。这意味着即便你现在不部署它,人们也会在它的基础上建立新的工作并在接下来的几个小时部署,推送。这样子的话,既然你真的不想其他人来push一些你写的休息的事情,人们倾向于确信当它合并的时候是否真的稳定。

我们的营火bot、hubot能让任何雇员部署,如此简单:

hubot deploy github to production

会部署代码并零停机时间的重新开始所有必须的步骤。你可以在GitHub看见这样的东西:



你能看见六个不同的人(包括一个支持的家伙和一个设计师)在一天中部署了24次。

我曾为分支提交过只包含了一行代码改动的commit。步骤是很简单、明了、可拓展并强大的 。你能用一个花费两周的包含了50个commits的分支,或者一个花了10分钟的comiit。这是一个如此简单且摩擦少的过程,以至于你不会因为一个commit而感到恼火,这意味着人们很少师徒去跳过或者绕开这些步骤除非改变小的可以忽略不计。

总结

    Git本身是复杂的难以理解的,让你使用的工作流程更加复杂而非必须只是简单的增加每个人日常的精神开销。我总是会宣扬在你的团队使用尽可能最简单的系统,直到它再也不能工作的时候也仅仅是增加必须增加的复杂度。

    对于需要在一个更长周期开发正式版本的release的团队,而且能够做到hot-fix和维护分支以及其他很少从迁移中产生的成本,git-flow非常有用而且我也是极力推荐使用的。

    对于已经建立迁移文化的团队,谁来每天push产品,谁持续的测试和部署,我会提议选择一些更简单的像Git Flow。






原创粉丝点击