Git 作为一个源码管理系统,不可避免涉及到多人协作。

  协作必须有一个规范的流程,让大家有效地合作,使得项目井井有条地发展下去。"协作流程"在英语里,叫做"workflow"或者"flow",原意是水流,比喻项目像水流那样,顺畅、自然地向前流动,不会发生冲击、对撞、甚至漩涡。

  蓝色可以叫主干提交记录线,紫色和绿色可以叫合并分支记录线

经典 branch 工作模式
如下是一个不错的代码管理模式,详细的可以参考 A successful Git branching model,也可以查看 本地文档 ,如下是一个简单介绍。

从上图可以看到主要包含下面几个分支,简单介绍如下:

master: 主分支,用来版本发布,通常
develop:日常开发分支,保存了开发的最新代码,用于每天的回归测试;
feature:新的特性或者功能开发分支,只与 develop 分支交互;
release:预发布分支,在特性开发基本测试完成后,准备发布前,用于发布前最后测试;
hotfix:线上 bug 修复分支。

Main Branches
含两个主分支 master 和 develop ,其中 origin/master 表示主分支, HEAD 始终是用于生产环境的代码。而 origin/develop 表示主开发分支,其中的 HEAD 表示最新提交的代码,这也就是每天用来编译测试的代码。

当开发分支的代码趋于稳定之后,且准备发布时,只需要打个发布的版本号标签 (tag) 即可。

因此,每次提交到主干时,也就意味着这是一个新的生产版本的发布,那么可以通过一个 hook 自动编译,生成生产环境的安装包。

----- 新建一个仓库,默认会有一个master分支
$ git init
$ echo 'Hello World!' > README
$ git add README
$ git commit -m 'Initial Commit' ----- 新建一个develop分支
$ git branch develop

上述的 main 和 develop 都可以称之为主干分支。

除了主干的分支外,还包括了一些其它分支,区别是这些分支有固定的生命周期,包括了 Feature Branches、Release Branches、Hotfix Branches 三种针对不同的场景,也对应了如何获取分支以及如何合并分支。

如上介绍的三种分支也可以被称为 Support Branches,接下来详细介绍这三种分支。

Feature Branches
特性分支用来开发一个新的特性,这一分支从 develop 创建,而且最终会合并到 develop 分支;当然,也有可能最终取消掉,这取决于最终产品的决策。

接下来看看如何使用。

----- . 创建新的特性分支
$ git checkout -b feature-foobar develop ----- . 执行一些操作,多次提交
$ echo "FOOBAR Feature 1" >> README
$ git commit -a -m "foobar feature 1"
$ echo "FOOBAR Feature 2" >> README
$ git commit -a -m "foobar feature 2" ----- 2.1 开发完成,接下来准备合并,先切换到develop分支
$ git checkout develop ----- 2.2 合并到develop主分支
$ git merge --no-ff feature-foobar ----- 2.3 删除原来的分支
$ git branch -d feature-foobar ----- 2.4 提交到远程仓库
$ git push origin develop

另外,需要注意的是,上述合并到主分支的时候,采用的是 --no-ff 模式。

该参数的作用是强行关闭 fast-forward 方式,该方式就是当条件允许的时候,git 直接把 HEAD 指针指向合并分支的头,完成合并。不过如果删除分支,由于这个过程中没有创建 commit,则会丢失分支信息,使用该参数将保留分支 commit 历史。

实际上,通过 git log 查看时,使用 --on-ff 会强制添加 commit ,否则看不到合并的信息。

另外,还有个参数 --squash,会把多次分支 commit 历史压缩为一次。

Release Branches
用于正式发布前的最后测试,尽量减少 bug 数目,添加元信息 (版本号以及发布日期等)。该分支从 develop 创建,可以合并到 develop 或者 master 分支,其命名为 release-* 。

合并到 master 之后就可以用于发布了,而之所以合并到 develop ,是为了将最新修改合并到新的开发分支。

----- . 创建分支,并更新文件一些头部信息等,然后提交
$ git checkout -b release-1.2 develop
$ ./bump-version.sh 1.2
$ git commit -a -m "Bumped version number to 1.2" ----- . 测试没有问题后,准备正式发布
$ git checkout master
$ git merge --no-ff release-1.2
$ git tag -a 1.2 ----- . 删除release分支
$ git checkout develop
$ git merge --no-ff release-1.2
$ git branch -d release-1.2

Hotfix Branches
该分支由于修复线上 bug,当线上代码出现 bug 时,从 master 开一个 hotfix 分支,修复 bug 之后再将 hotfix 分支合并到 master 分支并进行发布,同时也需要合并到 develop 分支上去。

可以发现,hotfix 和 release 分支功能类似,两者好处是不会打断 develop 分支正常功能开发。

----- . 从master获取分支
$ git checkout -b hotfix-1.2. master
$ ./bump-version.sh 1.2.
$ git commit -a -m "Bumped version number to 1.2.1" ----- . 然后修改代码修复bug,并提交
$ git commit -m "Fixed severe production problem" ----- . bug修复后,将该分支合并到master
$ git checkout master
$ git merge --no-ff hotfix-1.2.
$ git tag -a 1.2. ----- . 然后将hotfix合并到develop分支
$ git checkout develop
$ git merge --no-ff hotfix-1.2. ----- . 删除hotfix分支
$ git branch -d hotfix-1.2.

https://jin-yang.github.io/post/git-branch-model.html

本文介绍三种广泛使用的协作流程:

  • Git flow
  • Github flow
  • Gitlab flow

  如果你对Git还不是很熟悉,可以先阅读下面的文章。

  一、功能驱动

  本文的三种协作流程,有一个共同点:都采用"功能驱动式开发"(Feature-driven development,简称FDD)。

  它指的是,需求是开发的起点,先有需求再有功能分支(feature branch)或者补丁分支(hotfix branch)。完成开发后,该分支就合并到主分支,然后被删除。

  二、Git flow

  最早诞生、并得到广泛采用的一种协作流程,就是Git flow 。

  2. 1 特点

  它最主要的特点有两个。

  首先,项目存在两个长期分支。

  • 主分支master
  • 开发分支develop

  前者用于存放对外发布的版本,任何时候在这个分支拿到的,都是稳定的发布版;后者用于日常开发,存放最新的开发版。

  其次,项目存在三种短期分支。

  • 功能分支(feature branch)
  • 补丁分支(hotfix branch)
  • 预发分支(release branch)

  一旦完成开发,它们就会被合并进developmaster,然后被删除。

  Git flow 的详细介绍,请阅读我翻译的中文版《Git 分支管理策略》

  2. 2 评价

  Git flow的优点是清晰可控,缺点是相对复杂,需要同时维护两个长期分支。大多数工具都将master当作默认分支,可是开发是在develop分支进行的,这导致经常要切换分支,非常烦人。

  更大问题在于,这个模式是基于"版本发布"的,目标是一段时间以后产出一个新版本。但是,很多网站项目是"持续发布",代码一有变动,就部署一次。这时,master分支和develop分支的差别不大,没必要维护两个长期分支。

  三、Github flow

  Github flow 是Git flow的简化版,专门配合"持续发布"。它是 Github.com 使用的协作流程。

  3. 1 流程

  它只有一个长期分支,就是master,因此用起来非常简单。

  官方推荐的流程如下。

  第一步:根据需求,从master拉出新分支,不区分功能分支或补丁分支。

  第二步:新分支开发完成后,或者需要讨论的时候,就向master发起一个pull reqest(简称PR)。

  第三步:Pull Request既是一个通知,让别人注意到你的请求,又是一种对话机制,大家一起评审和讨论你的代码。对话过程中,你还可以不断提交代码。

  第四步:你的Pull Request被接受,合并进master,重新部署后,原来你拉出来的那个分支就被删除。(先部署再合并也可。)

  3. 2 评价

  Github flow 的最大优点就是简单,对于"持续发布"的产品,可以说是最合适的流程。

  问题在于它的假设:master分支的更新与产品的发布是一致的。也就是说,master分支的最新代码,默认就是当前的线上代码。

  可是,有些时候并非如此,代码合并进入master分支,并不代表它就能立刻发布。比如,苹果商店的APP提交审核以后,等一段时间才能上架。这时,如果还有新的代码提交,master分支就会与刚发布的版本不一致。另一个例子是,有些公司有发布窗口,只有指定时间才能发布,这也会导致线上版本落后于master分支。

  上面这种情况,只有master一个主分支就不够用了。通常,你不得不在master分支以外,另外新建一个production分支跟踪线上版本。

  四、Gitlab flow

  Gitlab flow 是 Git flow 与 Github flow 的综合。它吸取了两者的优点,既有适应不同开发环境的弹性,又有单一主分支的简单和便利。它是 Gitlab.com 推荐的做法。

  4. 1 上游优先

  Gitlab flow 的最大原则叫做"上游优先"(upsteam first),即只存在一个主分支master,它是所有其他分支的"上游"。只有上游分支采纳的代码变化,才能应用到其他分支。

  Chromium项目就是一个例子,它明确规定,上游分支依次为:

  1. Linus Torvalds的分支
  2. 子系统(比如netdev)的分支
  3. 设备厂商(比如三星)的分支

  4. 2 持续发布

  Gitlab flow 分成两种情况,适应不同的开发流程。

  对于"持续发布"的项目,它建议在master分支以外,再建立不同的环境分支。比如,"开发环境"的分支是master,"预发环境"的分支是pre-production,"生产环境"的分支是production

  开发分支是预发分支的"上游",预发分支又是生产分支的"上游"。代码的变化,必须由"上游"向"下游"发展。比如,生产环境出现了bug,这时就要新建一个功能分支,先把它合并到master,确认没有问题,再cherry-pickpre-production,这一步也没有问题,才进入production

  只有紧急情况,才允许跳过上游,直接合并到下游分支。

  4. 3 版本发布

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

  以后,只有修补bug,才允许将代码合并到这些分支,并且此时要更新小版本号。

  五、一些小技巧

  5. 1 Pull Request

  功能分支合并进master分支,必须通过Pull Request(Gitlab里面叫做 Merge Request)。

  前面说过,Pull Request本质是一种对话机制,你可以在提交的时候,@相关人员团队,引起他们的注意。

  5. 2 Protected branch

  master分支应该受到保护,不是每个人都可以修改这个分支,以及拥有审批 Pull Request 的权力。

  Github 和 Gitlab 都提供"保护分支"(Protected branch)这个功能。

  5. 3 Issue

  Issue 用于 Bug追踪和需求管理。建议先新建 Issue,再新建对应的功能分支。功能分支总是为了解决一个或多个 Issue。

  功能分支的名称,可以与issue的名字保持一致,并且以issue的编号起首,比如"15-require-a-password-to-change-it"。

  开发完成后,在提交说明里面,可以写上"fixes #14"或者"closes #67"。Github规定,只要commit message里面有下面这些动词 + 编号,就会关闭对应的issue。

  • close
  • closes
  • closed
  • fix
  • fixes
  • fixed
  • resolve
  • resolves
  • resolved

  这种方式还可以一次关闭多个issue,或者关闭其他代码库的issue,格式是 username/repository#issue_number

  Pull Request被接受以后,issue关闭,原始分支就应该删除。如果以后该issue重新打开,新分支可以复用原来的名字。

  5. 4 Merge节点

  Git有两种合并:一种是"直进式合并"(fast forward),不生成单独的合并节点;另一种是"非直进式合并"(none fast-forword),会生成单独节点。

  前者不利于保持commit信息的清晰,也不利于以后的回滚,建议总是采用后者(即使用--no-ff参数)。只要发生合并,就要有一个单独的合并节点。

  5. 5 Squash 多个commit

  为了便于他人阅读你的提交,也便于cherry-pick或撤销代码变化,在发起Pull Request之前,应该把多个commit合并成一个。(前提是,该分支只有你一个人开发,且没有跟master合并过。)

  这可以采用rebase命令附带的squash操作,具体方法请参考我写的《Git 使用规范流程》

http://kb.cnblogs.com/page/535581/

Git协作流程的更多相关文章

  1. Git协作流程(转)

    Git 作为一个源码管理系统,不可避免涉及到多人协作. 协作必须有一个规范的流程,让大家有效地合作,使得项目井井有条地发展下去."协作流程"在英语里,叫做"workflo ...

  2. 小团队Git协作流程

    git和svn 最大的差异在于git是分布式的管理方式而svn是集中式的管理方式. 集中式 集中式代码管理的核心是服务器,所有开发者在开始coding之前必须从服务器获取代码,然后开发,最后解决冲突, ...

  3. git 的安装使用以及协作流程

    git安装: sudo apt-get install git-core git使用: 转:https://www.liaoxuefeng.com/wiki/0013739516305929606dd ...

  4. SourceTree 实现 git flow 流程

    为什么使用 git 和 git flow,这篇文章 深入理解学习Git工作流 的内容相信能够给你一个完整的答案. 我们以使用SVN的工作流来使用git有什么不妥? git 方便的branch在哪里,团 ...

  5. 前端开发工程师 - 05.产品前端架构 - 协作流程 & 接口设计 & 版本管理 & 技术选型 &开发实践

    05.产品前端架构 第1章--协作流程 WEB系统 角色定义 协作流程 职责说明 第2章--接口设计 概述 接口规范 规范应用 本地开发 第3章--版本管理 见 Java开发工程师(Web方向) - ...

  6. GitHub团队协作流程

    说来惭愧,这么长时间,第一次参与修改开源项目,所以整理了一份GitHub团队协作流程,作为备忘,文章大部分内容参考https://www.cnblogs.com/schaepher/p/4933873 ...

  7. git详情、git工作流程、常用命令、忽略文件、分支操作、gitee远程仓库使用

    今日内容概要 git详情 git工作流程 git常用命令 过滤文件 分支操作 git远程仓库使用 可参照:https://www.cnblogs.com/liuqingzheng/p/15328319 ...

  8. git工作流程

    git工作流程 一般工作流程如下: 克隆 Git 资源作为工作目录. 在克隆的资源上添加或修改文件. 如果其他人修改了,你可以更新资源. 在提交前查看修改. 提交修改. 在修改完成后,如果发现错误,可 ...

  9. 怎样通过git协作开发

    近期iOS群里的一些小伙伴刚刚毕业,刚參加工作的小伙伴们,对于怎样进行git下的一个写作开发抱有较大的疑惑.今天小汤我就给大家分享个git下协作开发的小技巧. 怎样通过git协作开发? 当两个开发人员 ...

随机推荐

  1. Working with DVT Components

      Introduction to ADF Data Visualization Components - Graphs, Gauge, Maps, Pivot Table and Gantt Pur ...

  2. SpriteBuilder代码中弱引用(weak)需要注意的地方

    比如在GameScene类中有一个弹出菜单层实例的引用,我们有: @implementation GameScene{ //other ivars __weak GameMenuLayer *_pop ...

  3. 关于C++“加、减机制”的整理

    今天上C++的课,杨老师提到C++继承是“加机制”的,而没有像人类进化一样采取的是“减机制”,这样会导致代码的膨胀和冗余.回来后,特地查阅了一下资料,发现这方面的文章很少. 下边的资料摘自网上及杨老师 ...

  4. Access text files using SQL statements by DB Query Analyzer

    Access text files using SQL statements by DB Query Analyzer Ma Gen feng (Guangdong Unitoll Services ...

  5. The 2nd tip of DB Query Analyzer

    The 2nd tip of DB Query Analyzer                               Ma Genfeng   (Guangdong Unitoll Servi ...

  6. webapi从入门到放弃(一)OWIN 自寄宿模式

     1.创建web空项目 2.创建完如图 3.安装如下程序包Microsoft.AspNet.WebApi.Core (5.2.4)Microsoft.Owin.Host.SystemWeb (4.0. ...

  7. Android两级导航菜单栏的实现--FragmentTabHost结合ViewPager与Android 开源项目PagerSlidingTabStrip

    http://www.cnblogs.com/aademeng/articles/6119737.html 转载注:简单总结一下,外层Tab用TabHost,类层Tab用Viepager+Framen ...

  8. oracle数据库的备份与还原(本地及远程操作)

    数据的导出 exp qh/qh@qh  file='d:\backup\qh\qh20060526.dmp'  grants=y  full=n  1 将数据库TEST完全导出,用户名system 密 ...

  9. day11_jsp/EL/JSTL学习笔记

    一.jsp概述 JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP实际上就是Servlet. JSP这门技术的最大 ...

  10. flash builder 4.6与myecilpse 10.7集成

    一.在flash builder 4.0以后就没有单独提供插件版的flash builder了,因此必须先安装完整版的flash builder,再进行插件集成. 二.集成过程比较简单但也有几个要注意 ...