[GitHub Flow]
首先来一个地址 http://xgithubs.com/index.html , 能下载程序员平时使用的常规工具, 还有github star fork follow watch 的功能, 能加几千星, 贼好使,需要star 的朋友可以自行下载使用, chrome 插件, 贼好使*3
git-flow 的问题
我到处旅行,向人们教授 Git,几乎我最近完成的每一堂课和研讨会都问我对git-flow 的看法。我总是回答说我认为这很棒——它采用了一个系统 (Git),它拥有一百万个可能的工作流程,并记录了一个经过良好测试、灵活的工作流程,它以一种相当简单的方式适用于许多开发人员。它已成为一种标准,以便开发人员可以在项目或公司之间移动并熟悉这种标准化的工作流程。
然而,它确实有它的问题。我从人们那里听到了很多意见,不喜欢新功能分支从而不是开始develop
,master
或者不喜欢它处理修补程序的方式,但这些都相当次要。
对我来说更大的问题之一是它比我认为大多数开发人员和开发团队实际需要的要复杂。开发了一个大的帮助脚本来帮助执行流程已经足够复杂了。虽然这很酷,但问题是它不能在 Git GUI 中强制执行,只能在命令行上执行,所以唯一必须真正很好地学习复杂工作流程的人,因为他们必须手动完成所有步骤,是同样的人对系统不够满意,无法从命令行使用它。这可能是一个大问题。
这两个问题都可以通过更简化的流程轻松解决。在 GitHub,我们不使用 git-flow。我们使用并且一直在使用更简单的 Git 工作流程。
它的简单性给它带来了许多优点。一是人们很容易理解,这意味着他们可以快速掌握它,而且他们很少会搞砸或不得不撤消他们做错的步骤。另一个是我们不需要包装脚本来帮助执行或遵循它,因此使用 GUI 等不是问题。
GitHub 流
那么,我们为什么不在 GitHub 上使用 git-flow 呢?嗯,主要问题是我们一直在部署。git-flow 流程主要围绕“发布”而设计。我们并没有真正的“发布”,因为我们每天都部署到生产环境——通常一天几次。我们可以通过我们的聊天室机器人来做到这一点,这与我们的 CI 结果显示在同一个地方。我们试图使测试和运输过程尽可能简单,让每个员工都感到舒适。
定期部署有很多优点。如果每隔几个小时部署一次,几乎不可能引入大量的大错误。可以引入一些小问题,但可以很快地修复和重新部署它们。通常,您必须执行“修补程序”或正常流程之外的其他操作,但这只是我们正常流程的一部分 - 修补程序和非常小的功能在 GitHub 流程中没有区别。
始终部署的另一个优势是能够快速解决各种问题。我们可以对引起我们注意的安全问题做出响应,或者以难以置信的速度实现小而有趣的功能请求,但我们可以使用与处理正常甚至大型功能开发相同的过程来解决这些更改。这都是相同的过程,而且非常简单。
我们是如何做到的
那么,什么是 GitHub Flow?
-
master
分支中的任何东西都是可部署的 - 要处理新事物,请创建一个描述性命名的分支
master
(即new-oauth2-scopes
:) - 在本地提交到该分支并定期将您的工作推送到服务器上的同名分支
- 当您需要反馈或帮助,或者您认为分支已准备好合并时,请打开拉取请求
- 其他人审核并签署该功能后,您可以将其合并到主
- 一旦它被合并并推送到“master”,您可以并且应该立即部署
这就是整个流程。它非常简单、非常有效,适用于相当大的团队——GitHub 现在有 35 名员工,其中可能有 15-20 人同时在同一个项目 (github.com) 上工作。我认为大多数开发团队——同时处理可能产生冲突的相同逻辑代码的团队——都在这个规模左右或更小。尤其是那些进步到足以进行快速和一致部署的人。
所以,让我们依次看看这些步骤中的每一个。
#1 - master 分支中的任何东西都是可部署的
这基本上是系统唯一的硬性规则。只有一个分支具有任何特定且一致的含义,我们将其命名为master
。对我们来说,这意味着它已经部署,或者最坏的情况将在数小时内部署。这种情况非常罕见(分支被移回较旧的提交以恢复工作) - 如果存在问题,提交将被恢复或将引入新的提交来解决问题,但分支本身几乎永远不会回滚。
分支是稳定的master
,从它部署或创建新分支总是安全的。如果您将未经测试或破坏构建的东西推给掌握,那么您就破坏了开发团队的社会契约,您通常会对此感到非常难过。我们推送的每个分支都有测试运行并报告到聊天室,所以如果你没有在本地运行它们,你可以简单地推送到服务器上的一个主题分支(甚至是一个单一提交的分支)并等待Jenkins告诉你它是否通过了一切。
您可以拥有deployed
仅在部署时更新的分支,但我们不这样做。curl
如果我们需要进行比较,我们只需通过 webapp 本身和它公开当前部署的 SHA 。
#2 - 从 master 创建描述性分支
当你想开始做任何事情时,你可以从 stable 分支创建一个描述性命名的master
分支。现在 GitHub 代码库中的一些示例是user-content-cache-key
,submodules-init-task
或redis2-transition
. 这有几个优点 - 一个是当您获取时,您可以看到其他人一直在研究的主题。另一个是如果你暂时放弃一个分支,然后再回到它,很容易记住它是什么。
这很好,因为当我们转到 GitHub 分支列表页面时,我们可以很容易地看到最近在哪些分支上工作,以及他们在这些分支上做了多少工作。
它几乎就像一个具有当前粗略状态的即将推出的功能列表。如果您不使用它,这个页面非常棒 - 它只向您显示相对于您当前选择的分支具有独特工作的分支,并对它们进行排序,以便最近工作的分支位于顶部。如果我真的很好奇,我可以单击“比较”按钮来查看该分支独有的实际统一差异和提交列表是什么。
因此,在撰写本文时,我们的存储库中有 44 个分支,其中包含未合并的工作,但我也可以看到上周只有大约 9 或 10 个分支被推送到。
#3 - 不断推送到命名分支
与 git-flow 的另一个大区别是我们不断地推送到服务器上的命名分支。由于我们真正需要担心的唯一事情是master
从部署的角度来看,推送到服务器不会弄乱任何人或混淆事情 - 不是所有事情都master
只是正在处理的事情。
它还确保在笔记本电脑丢失或硬盘驱动器故障的情况下始终备份我们的工作。更重要的是,它让每个人都保持不断的沟通。一个简单的 'git fetch' 基本上会给你一个 TODO 列表,列出每个人当前正在做什么。
$ git fetch
remote: 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 分支列表页面,它还让每个人都可以看到其他人正在做什么,以便他们可以检查它们,看看他们是否想提供帮助。
#4 - 随时打开拉取请求
GitHub 有一个很棒的代码审查系统,叫做Pull Requests,我担心没有足够的人知道。许多人将它用于开源工作——分叉项目、更新项目、向维护者发送拉取请求。但是,它也可以很容易地用作内部代码审查系统,这就是我们所做的。
实际上,我们更多地将其用作分支对话视图,而不是拉取请求。您可以在 GitHub 中的单个项目(公共或私有)中将拉取请求从一个分支发送到另一个分支,因此您可以使用它们说“我需要帮助或对此进行审核”以及“请合并此”。
在这里,您可以看到 Josh 抄送 Brian 以供审查,而 Brian 则对其中一行代码提出了一些建议。再往下,我们可以看到 Josh 承认了 Brian 的担忧并推动了更多的代码来解决这些问题。
最后,您可以看到我们仍处于试用阶段——这还不是一个部署就绪的分支,我们在真正想要将其合并到master
部署之前很久就使用拉取请求来审查代码。
如果您卡在功能或分支的进度中并需要帮助或建议,或者如果您是开发人员并且需要设计师来审查您的工作(反之亦然),或者即使您只有一些屏幕截图或很少或没有代码比较或一般的想法,你打开一个拉取请求。您可以通过添加@username 来抄送 GitHub 系统中的人员,因此如果您想要特定人员的评论或反馈,您只需在 PR 消息中抄送他们(正如您在上面看到的 Josh 所做的那样)。
这很酷,因为拉取请求功能让您可以评论统一差异中的各个行、单个提交或拉取请求本身,并将所有内容内联到单个对话视图中。它还可以让你继续推送到分支,所以如果有人评论你忘记做某事或代码中有错误,你可以修复它并推送到分支,GitHub 会在对话视图中显示新提交你可以继续在这样的分支上迭代。
如果分支打开时间过长,你觉得它与 master 分支不同步,你可以将 master 合并到你的主题分支中并继续。您可以在拉取请求讨论或提交列表中轻松查看分支最后一次与“主”同步的时间。
当一切都在分支上真正完成并且您觉得它已准备好部署时,您可以继续下一步。
#5 - 仅在拉取请求审查后合并
我们不只是直接在master
一个主题分支上工作或在我们认为完成时将其合并到一个主题分支上——我们试图从公司中的其他人那里获得批准。这通常是 +1 或表情符号或“:shipit:”评论,但我们试图让其他人看到它。
一旦我们得到它,并且分支通过 CI,我们可以将它合并到 master 中进行部署,当我们推送它时,它将自动关闭 Pull Request。
#6 - 审查后立即部署
最后,您的工作完成并合并到master
分支中。这意味着即使您现在不部署它,人们也会基于它进行新的工作,而下一次部署(可能会在几个小时内发生)会将其推出。因此,由于您真的不希望其他人推送您编写的破坏事物的内容,因此人们倾向于确保它在合并时确实是稳定的,并且人们也倾向于推送他们自己的更改。
我们的篝火机器人 hubot 可以为任何员工进行部署,所以很简单:
hubot depoy github to production
将部署代码并以零停机时间重新启动所有必要的流程。您可以在 GitHub 上看到这很常见:
你可以看到 6 个不同的人(包括一个支持人员和一个设计师)在一天内部署了大约 24 次。
我已经为一个包含一行更改的提交的分支做到了这一点。该过程简单、直接、可扩展且功能强大。您可以使用具有 50 次提交的功能分支来完成此操作,这些提交需要 2 周,或者 1 次提交需要 10 分钟。这是一个如此简单且无摩擦的过程,即使是 1 次提交,您也不会因为必须这样做而烦恼,这意味着人们很少尝试跳过或绕过该过程,除非更改非常小或微不足道以至于无关紧要.
这是一个非常简单而强大的过程。我想大多数人都会同意 GitHub 有一个非常稳定的平台,一旦出现问题就会很快得到解决,而且新功能的推出速度很快。质量或稳定性没有妥协,因此我们可以获得更快、更简单或更少流程。
结论
Git 本身理解起来相当复杂,使您使用它的工作流程比必要的复杂得多,这只会给每个人的一天增加更多的精神开销。我总是提倡使用最简单的系统,为你的团队工作,直到它不再工作,然后只在绝对需要时增加复杂性。
对于必须以较长时间间隔(发布之间的几周到几个月)进行正式发布的团队,并且能够进行热修复和维护分支以及其他因不频繁发布而产生的事情,git-flow使感觉,我会高度提倡使用它。
对于已经建立了交付文化、每天推动生产、不断测试和部署的团队,我建议选择像 GitHub Flow 这样更简单的东西。