在分享开始前...
- Hello, World! I am Tristan. (特里斯谭)
- 喜欢和优秀的人做挑战的事情
- 崇尚自由与分享的互联网精神
- The most important thing: I have dream and passion
- 2015年11月10日,在这个双十一即将到来的时分,我做出了一个重要的决定,就是开始写文章。
- 作为一个技术团队的负责人和一个标准的ScrumMaster,让我来进入第一篇分享的话题 -- GitFlow
关于Git的一段话
目前在开源技术社区,Git作为版本控制工具,正逐步取代SVN的地位。Git对分布式开发,分支开发等有更好的支持,也更容易在各个开发分支上及时反应主干的最新更新,避免SVN在最后提交分支代码时发现和主干代码差别太大难以merge成功。但是Git的学习成本较高,如何和网站开发流程相结合还缺乏最佳实践和使用规范。不过相信Git成为网站的标准版本控制工具是迟早的。
——《大型网站技术架构》作者、原阿里巴巴技术专家 李智慧(2012年底)
猜猜下面几个关键词是什么
- Tuesday, January 05, 2010
- A successful Git branching model
- http://nvie.com/
- Vincent Driessen
GitFlow是什么
Git Flow是构建在Git之上的一个组织软件开发活动的模型,是在Git之上构建的一项软件开发最佳实践。Git Flow是一套使用Git进行源代码管理时的一套行为规范和简化部分Git操作的工具。
2010年1月,在一篇名为“一种成功的Git分支模型”的博文中,@nvie介绍了一种在Git之上的软件开发模型。通过利用Git创建和管理分支的能力,为每个分支设定具有特定的含义名称,并将软件生命周期中的各类活动归并到不同的分支上。实现了软件开发过程不同操作的相互隔离。这种软件开发的活动模型被nvie称为“Git Flow”。
下面让我们用一幅图来了解GitFlow
Git-branching-model.png
Git Flow中的分支
Git Flow模型中定义了主分支和辅助分支两类分支。其中主分支用于组织与软件开发、部署相关的活动;辅助分支组织为了解决特定的问题而进行的各种开发活动。
主分支
主分支是所有开发活动的核心分支。所有的开发活动产生的输出物最终都会反映到主分支的代码中。主分支分为master分支和development分支。
main.png1. master分支
master分支上存放的应该是随时可供在生产环境中部署的代码(Production Ready state)。当开发活动告一段落,产生了一份新的可供部署的代码时,master分支上的代码会被更新。同时,每一次更新,最好添加对应的版本号标签(TAG)。
2. develop分支
develop分支是保存当前最新开发成果的分支。通常这个分支上的代码也是可进行每日夜间发布的代码(Nightly build)。因此这个分支有时也可以被称作“integration branch”。
当develop分支上的代码已实现了软件需求说明书中所有的功能,通过了所有的测试后,并且代码已经足够稳定时,就可以将所有的开发成果合并回master分支了。对于master分支上的新提交的代码建议都打上一个新的版本号标签(TAG),供后续代码跟踪使用。
因此,每次将develop分支上的代码合并回master分支时,我们都可以认为一个新的可供在生产环境中部署的版本就产生了。通常而言,“仅在发布新的可供部署的代码时才更新master分支上的代码”是推荐所有人都遵守的行为准则。基于此,理论上说,每当有代码提交到master分支时,我们可以使用Git Hook触发软件自动测试以及生产环境代码的自动更新工作。这些自动化操作将有利于减少新代码发布之后的一些事务性工作。
辅助分支
辅助分支是用于组织解决特定问题的各种软件开发活动的分支。辅助分支主要用于组织软件新功能的并行开发、简化新功能开发代码的跟踪、辅助完成版本发布工作以及对生产代码的缺陷进行紧急修复工作。这些分支与主分支不同,通常只会在有限的时间范围内存在。
辅助分支包括:
- 用于开发新功能时所使用的feature分支;
- 用于辅助版本发布的release分支;
- 用于修正生产代码中的缺陷的hotfix分支。
以上这些分支都有固定的使用目的和分支操作限制。从单纯技术的角度说,这些分支与Git其他分支并没有什么区别,但通过命名,我们定义了使用这些分支的方法。
1. feature分支
使用规范:
可以从develop分支发起feature分支
代码必须合并回develop分支
feature分支的命名可以使用除master,develop,release-,hotfix-之外的任何名称
feature分支(有时也可以被叫做“topic分支”)通常是在开发一项新的软件功能的时候使用,这个分支上的代码变更最终合并回develop分支或者干脆被抛弃掉(例如实验性且效果不好的代码变更)。
一般而言,feature分支代码可以保存在开发者自己的代码库中而不强制提交到主代码库里。
feaure.png2. release分支
使用规范:
可以从develop分支派生
必须合并回develop分支和master分支
分支命名惯例:release-*
release分支是为发布新的产品版本而设计的。在这个分支上的代码允许做小的缺陷修正、准备发布版本所需的各项说明信息(版本号、发布时间、编译时间等等)。通过在release分支上进行这些工作可以让develop分支空闲出来以接受新的feature分支上的代码提交,进入新的软件开发迭代周期。
当develop分支上的代码已经包含了所有即将发布的版本中所计划包含的软件功能,并且已通过所有测试时,我们就可以考虑准备创建release分支了。而所有在当前即将发布的版本之外的业务需求一定要确保不能混到release分支之内(避免由此引入一些不可控的系统缺陷)。
成功的派生了release分支,并被赋予版本号之后,develop分支就可以为“下一个版本”服务了。所谓的“下一个版本”是在当前即将发布的版本之后发布的版本。版本号的命名可以依据项目定义的版本号命名规则进行。
3. hotfix分支
使用规范:
可以从master分支派生
必须合并回master分支和develop分支
分支命名惯例:hotfix-*
除了是计划外创建的以外,hotfix分支与release分支十分相似:都可以产生一个新的可供在生产环境部署的软件版本。
当生产环境中的软件遇到了异常情况或者发现了严重到必须立即修复的软件缺陷的时候,就需要从master分支上指定的TAG版本派生hotfix分支来组织代码的紧急修复工作。
这样做的显而易见的好处是不会打断正在进行的develop分支的开发工作,能够让团队中负责新功能开发的人与负责代码紧急修复的人并行的开展工作。
hotfix.png再用另一张图回顾GitFlow
git-flow-overview.jpg更进一步
Git Flow开发模型从源代码管理角度对通常意义上的软件开发活动进行了约束。应该说,为我们的软件开发提供了一个可供参考的管理模型。Git Flow开发模型让nvie的开发代码仓库保持整洁,让小组各个成员之间的开发相互隔离,能够有效避免处于开发状态中的代码相互影响而导致的效率低下和混乱。
所谓模型,在不同的开发团队,不同的文化,不同的项目背景情况下都有可能需要进行适当的裁剪或扩充。祝各位好运!
PS:为了简化使用Git Flow模型时Git指令的复杂性,nvie开发出了一套git增强指令集。可以运行于Windows、Linux、Unix和Mac操作系统之下。有兴趣的同学可以去看看。
如何使用GitFlow
-
命令行方式 (忽略,繁琐,不推荐)
-
使用可视化操作工具
使用SourceTree作为Git分支管理工具,默认集成了GitFlow可视化管理工具。推荐使用此方式进行分支管理。(注意:没有初始化过GitFlow的工程首次需要进行GitFlow初始化,点击一个按钮即可)
注意:以下操作以Mac上的SourceTree作为示例,在Windows上界面显示稍有差别,但是操作和功能基本一致
- 打开SourceTree主界面
- 点击右上角的GitFlow按钮
- 进如GitFlow分支管理菜单界面
-
代码管理在团队开发中的一些思考
-
极小的团队(1-2个人)进行开发是否有必要使用GitFlow?
-
每次commit意味着什么?
-
Git使用的技巧:如何合并提交,撤销提交?
对团队开发的帮助
- 软件开发是一门艺术,但是需要严谨、协作的态度。
- 任何事情做的越专业就越会形成一套较为成熟的方法论。
- 再优秀的工程师在团队中也要和共同的目标达成一致(敏捷宣言)。
- 希望通过GitFlow可以指导团队拥有更高效的代码分支管理准则。
- 示例:某开发团队的 Git分支管理规范
(未必是良好的典范,但是一个有效的输出成果)
在分享后...(个人感悟)
- 相信坚持的力量,定期分享和总结会让你的成长的更加坚实有力
- 感谢分享的精神,我一直以为互联网的感动中国奖应该颁发给这些无私分享的人们
网友评论
我是这个项目的管理员,用sourcetree 采用git flow的方式初始化了这个仓库,然后提交到远程git(此时默认创建了master和develop两个分支), 其他成员clone下来后, 点击develop分支,再点击sourceTree右上角的git 工作流按钮,按道理弹出的窗口里面应该是 提示创建新功能的选项, 而实际上他们弹出的窗口里面却是 采用git flow初始化这个仓库。 我现在懵逼了,那这样的话,git flow仅仅是约束我个人,感觉也没什么意义呀 .... 是我使用方式不对吗?