Git 工做流程及分支策略

本文首发于 刘星的我的网站html

image.png

Git 是目前世界上最早进的分布式版本控制系统。它使咱们更方便的跟踪,管理和组织代码。也帮助了咱们更好的与其余开发者进行协做开发。可是没有规矩不成方圆。协做开发必须有一个规范来约束各个贡献者的行为。这个规范就是 Git 工做流程(Git Workflow),也为咱们规范各个分支管理策略等行为。

Git 工做流程是有关如何使用 Git 以高效协做开发的规则或策略建议,下文这些常见工做流程只是做为指导参考,这些工做流不是一成不变的,咱们应该根据本身的项目选择或制定合适本身的工做流。git

集中式工做流

首先咱们来介绍最简单粗暴的集中式工做流,若是你用过SVN,那么你能够无痛切换到 Git 集中式工做流。该工做流只用到 master 这一个主分支来维护咱们的代码,这也是该工做流的主要工做方式。github

工做流程示例

一、首先 clone 远程仓库到本地apache

git clone ssh://user@host/path/to/repo.git

二、而后在本地的 master 分支作出修改完成开发后,建立一个提交bash

git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件

三、而后推送到远程仓库服务器

git push origin master

四、 若是此时本地仓库与远程仓库有了分歧,Git 将拒绝操做并报错。这时咱们就应该先 pull 远程仓库的修改到本地仓库后再解决从新推送app

git pull --rebase origin master

五、若是有冲突,Git 会在合并有冲突的提交处暂停 rebase 过程,并报出错误信息,咱们在解决掉冲突后可使用一下命令将更改加入暂存区后继续只能执行 rebase:框架

git add <some-file>
git rebase --continue

若是遇到一个搞不定的冲突,这可使用一下命令来终止 rebasessh

git rebase --abort

主要遵循原则

  • 只用到 master 这一个分支,全部的修改都推送到 master 分支
  • master 分支表明了项目的正式发布版本,因此提交历史应该被尊重且是稳定不变的
  • pull 代码时, 最好使用 rebase 而不是生成一个 merge commit

优势

  • 集中式工做流主要优势是简单,很是适合小型团队
  • 对于要从 SVN 迁移过来的团队来讲很友好

缺点

  • 当您的团队规模扩大时,上面详述的冲突解决过程可能会成为瓶颈
  • 彻底没有发挥 Git 的优点,在实际使用 Git 协做的项目开发中不多使用集中式工做流

若是在稍大的团队中使用前面的集中式工做流,那么可能会在解决冲突中浪费不少时间。在实际开发中咱们基本上都是都 功能驱动式开发,基于功能需求,建立相应的分支进行开发,完成开发合并到主分支后再被删除掉。接下来咱们介绍的三个工做流:GitHub Flow,Git Flow 及 Gitlab Flow 都是基于不一样的分支管理策略运做的。分布式

GitHub Flow 工做流

GitHub Flow 是一个轻量级的基于分支的工做流程。它由 GitHub 在 2011 年建立。分支是 Git 中的核心概念,而且 GitHub 工做流程中的一切都以此为基础。

最重要的的一点就是:main / master分支中的任何内容始终都是可部署的。其余分支(功能分支)建立用于新功能和错误修复的工做,而且在工做完成并通过检查后,这些分支将合并回到主分支中后删除。这些分支名应该是具备描述性的如 refactor-authentication, user-content-cache-key, make-retina-avatars

工做流程示例

一、首先 clone 远程仓库到本地

git clone ssh://user@host/path/to/repo.git

二、根据要实现的功能建立一个新的分支,分支名应该具备描述性,如实现鉴权功能:feature-auth

git checkout -b feature-auth

三、而后将新工做提交到该分支下,并按期将工做推送到远程仓库

# 建立一个commit
git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件

# 将分支推送到远程仓库
git push --set-upstream origin feature-auth

四、当你须要帮助或者反馈,或是你以为你已经完成该功能的工做准备合进主分支的时候建立 pull request

五、当你的这部分工做在 pull request 中,被 review 以及 approved 后,则能够合并到主分支。

git checkout master
git pull
git pull origin feature-auth
git push

六、合并到主分支后,应当即对其进行部署

主要遵循原则

  1. master 分支中的任何内容都是可部署的
  2. 要进行新的工做,须要从主分支master 建立出一个分支,并给出描述性的名称(如:new-oauth2-scopes
  3. 本地的修改提交到该分支,并按期将你的工做推送到服务器上的同一命名分支
  4. 当你须要反馈或帮助时,或者你认为分支已准备好进行合并时,请打开一个Pull Request
  5. 在其余人 Review 并 Approved 该功能后,你能够将其合并到 master
  6. 合并并推送到后主分支master,你能够而且应该当即进行部署

优势

  • 相比于前文介绍的集中式流程更为合理实用,能够减小工做中的冲突
  • 因为工做流程的简单性,此 Git 分支策略对进行持续交付和持续集成很友好。
  • 当须要在生产中维护单个版本时,它是理想的选择
  • 这个 Git 分支策略很是适合小型团队和 Web 应用程序

缺点

  • 这种 Git 分支策略没法同时支持多个版本的代码的部署
  • 没有解决部署、环境区分、 releases、Bug 修复相关的问题
  • 生产代码容易变得不稳定

Git Flow 工做流

基于功能分支的工做流是一中至关灵活的方式。可是问题也是有时候过于灵活。对于大型团队,经常须要给不一样分支分配一个更具体的角色。 Git Flow 工做流是管理功能开发、预发布和维护的经常使用模式。

Git Flow 是最先诞生而且至关流行的工做流程。它由 Vincent Driessen 于 2010 年建立。Git Flow 工做流定义了一个围绕项目发布的严格分支模型。虽然比 GitHub Flow 的功能分支工做流复杂一点,但提供了用于一个健壮的用于管理大型项目的框架。

Git Flow 工做流没有用超出功能分支工做流的概念和命令,Git Flow 为不一样的分支分配一个很明确的角色,并定义分支之间如何和何时进行交互。

工做流程示例

假设你已经建立好了中央仓库,而且已将其 clone 到本地

一、首先咱们来从主分支建立一个开发分支 develop, 并推送到服务器

git branch develop
git push -u origin develop

之后这个分支将会包含了项目的所有历史,而 master 分支将只包含了部分历史

二、接下来咱们开始开发新功能,基于 develop 分支建立新的功能分支

git checkout -b some-feature develop

并在本身的功能分支上进行开发、建立提交:

git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件

三、当你在你的分支上完成工做,准备好进行合并时,请打开一个 Pull Request,用于合并到develop分支。若是你的团队没使用 Pull Request 则能够直接合并到本地的 develop 分支而后推送到中央仓库。

git pull origin develop
git checkout develop

git merge --no-ff some-feature
git push
# 删除本地分支
git branch -d some-feature

而且在功能分支合并后应该当即删除

四、当咱们的 develop 分支进行到须要发布时,须要从develop分支建立一个新的发布分支,命名为release-*release/*。这一步也肯定了发布的版本号:

git checkout -b release-0.1.0 develop

这个分支是一个预发布的版本,只作 bug 修复、文档生成等面向发布的任务。新功能再也不添加到这个分支上

五、通过一系列测试确认没有问题,准备好了对外发布后,咱们须要将发布分支合并到 master 分支,并打下 tag

git checkout master
git merge --no-ff release-0.1
git push
git tag -a 0.1 -m "release 0.1 publish" master
git push --tags

六、同时咱们还须要将这个发布分支合并回去 master 分支

git checkout develop
git merge --no-ff release-0.1.0
git push

最后咱们还须要删除掉这个发布分支 release-0.1.0

七、若是咱们的线上版本出现问题时,就须要建立一个维护分支,用于快速给产品打补丁。这个维护分支须要从master分支上建立,提交修改以解决问题,而后再直接合并回master分支:

git checkout -b hotfix-auth master

修复完成后将其合并到 master 分支

git checkout master
git merge --no-ff hotfix-auth
git push

同时打下新的 tag

git tag -a 0.1.1 -m "release 0.1.1 publish" master
git push --tags

一样也须要将修复分支合并到 develop 分支

git checkout develop
git merge --no-ff hotfix-auth
git push

最后删除掉这个热修复分支

git branch -d hotfix-auth

主要遵循原则

它基于两个长期的主要分支:

  • 主分支 master 该分支包含生产代码。 该分支是稳定的发布版
  • 开发分支 develop 此分支包含预生产代码。全部的功能分支完成后须要合并到该分支

其次在开发中还有三种短时间分支

  • 功能分支(feature branch)功能分支用于为即将发布的版本开发新功能。从develop分支中检出也必须合并回develop
  • 补丁分支(hotfix branch)补丁分支 用于修复线上 bug, 从 master 分支上面检出。修复结束之后,再合并进 master 和 develop 分支
  • 预发分支(release branch)预发布分支用于生成一个预发布版本进行测试 预发布分支是从 develop 分支上面分出来的,预发布结束之后,必须合并进 Develop 和 Master 分支。它的命名,能够采用 release-*的形式。

优势

  • 整个项目生命周期内,分支状态十分干净,各个分支各司其职
  • 分支的命名遵循系统的模式,使其更易于理解
  • masterdevelop 分支分别记录发布和功能开发的历史
  • 因为有发布分支,其余暂不发布的功能的开发不受发布的影响,能够继续提交
  • 维护分支能快速打补丁,不影响正在开发的功能
  • 当生产中须要多个版本时,它是理想的选择

缺点

  • 较为复杂
  • Git 历史记录变得不可读
  • 须要维护两个长期分支 masterdevelop
  • 不方便持续交付和持续集成

Gitlab Flow 工做流

GitLab Flow 是经过建立工做流 GitLab在 2014 年。它将功能驱动的开发和功能分支以及问题跟踪结合在一块儿。它是 Git Flow 与 GithubFflow 的综合。它吸收了二者的优势,既有适应不一样开发环境的弹性,又有单一主分支的简单和便利。GitLab Flow 和 GitHub Flow 之间的最大区别是 GitLab Flow 中的环境分支支持(例如stagingproduction),

GitLab Flow 的最大原则叫作"上游优先"(upsteam first),即只存在一个主分支master,它是全部其余分支的"上游"。只有上游分支采纳的代码变化,才能应用到其余分支。

GitLab Flow 分红两种情形来应付不一样的开发流程

持续发布

对于持续发布的项目,它建议在master分支之外,再创建不一样的环境分支,每一个环境都会有对应的分支。好比,开发环境的分支是master,预发环境的分支是pre-production,生产环境的分支是production

  • 开发分支 master 用于发布到测试环境,该分支为受保护的分支
  • 预发分支 pre-production 用于发布到预发环境,上游分支为 master
  • 正式分支 production 用于发布到正式环境,上游分支为 pre-production

若是生产环境(production)发生错误,则要建一个新分支修改完后合并到最上游的开发分支(master)此时就是 Upstream first),且通过测试,再继续往 pre-production branch,要通过测试没有问题了才可以再往下合并到生产环境。

版本发布

对于"版本发布"的项目,建议的作法是每个稳定版本,都要从master分支拉出一个分支,好比2-3-stable2-4-stable等等。

再出现 bug 后,根据对应的 release branch 建立一个修复分支,修复工做万和城呢个后,同样要按着上游优选的原则,先合并到 master 分支,通过测试才能到才可以合并到 release 分支,而且此时要更新小版本号。

工做流程示例

和以前同样。首先 clone 项目到本地

一、当咱们要实现新功能或是修复 bug 时。从 master 检出新的分支如:feature-auth

git checkout -b feature-auth

二、而后在该分支下进行工做,完成后建立提交

git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件

推送代码到远程仓库,

git push origin feature-auth

三、代码推送到仓库后,自定运行 GitLab CI

四、当咱们开发完成准备合并进 master 时,在 GitLab 上建立一个 Merge Request

五、项目管理者进行代码审查,经过后,合并到master

六、运行第二次 GitLab CI

七、经过相应的测试后,将master分支合并到stable,若是是新版本则建立一个新的stable分支

八、为stable打上 tag,并进行发布

主要遵循原则

  1. 使用功能分支,不直接提交(commit)到 master 分支
  2. 测试全部的提交,而不只仅只在 master 分支上
  3. 在全部的提交上,运行全部的测试(若是你的测试时间长于 5 分钟则让它们并行)
  4. 在合并到 master 以前执行代码审查,而不是过后审查
  5. 部署是自动的,并基于分支或标签(tag)
  6. 标签(tag)是由用户设置的,而不是由 CI 建立
  7. 发布(release)是基于标签(tag)的
  8. 永远不对已推送的提交(pushed commits)进行变基(rebase)
  9. 每一个人都从 master 分支开始工做,目标也是 master 分支
  10. 在 master 分支中修正错误,其次再到发布分支
  11. 提交信息(commit message)应体现意图

优势

  • 它定义了如何进行持续集成和持续交付
  • Git 历史记录干净、易读

缺点

  • 相比较于 GitHub Flow 更复杂
  • 当须要在生产中维护多个版本时,它可能会像 Git Flow 同样变得复杂

总结及建议

没有一个万能的适合全部项目的 Git 工做流程及分支策略,不管最终选择哪一种策略,你均可以经过进一步的修改来优化它。就像前文所说的,Git 工做流程对咱们提高团队生产力很是重要,在制定咱们的工做流程时,应该尽可能符合咱们的项目具体业务需求及开发环境。可是也有以下几点小建议:

  • 临时分支不该该存在过久,每一个分支应尽可能保持精简,用完即删
  • 工做流应该尽可能简单,同时方便回滚
  • 工做流程应该符合咱们的项目发布计划

参考连接

本文完

欢迎能够关注个人公众号,一块儿玩耍。有技术干货也有扯淡乱谈

左手代码右手砖,抛砖引玉

相关文章
相关标签/搜索