热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

请指定您要合并哪一个分支_Git分支管理最佳实践

点击上方蓝字,关注我们前言Git是目前最流行的源代码管理工具。大量的软件项目由GitHub、Bitbucket和GitLab这样的云服务平台或是私有的Git仓库来管理
87bda088f80d276b256279247af58532.gif

点击上方蓝字,关注我们

a80fb883bc4d45b5a275f9f7e392027c.gif

6d7cd5686002f31b6339fe8f5b8c3625.png

前言Git 是目前最流行的源代码管理工具。大量的软件项目由 GitHub、Bitbucket 和 GitLab 这样的云服务平台或是私有的 Git 仓库来管理。在使用 Git 时通常会遇到的一个问题是采用何种分支管理实践,即如何管理仓库中作用不同的各类分支。和软件开发中的其他实践一样,Git 分支管理并没有普遍适用的最佳做法,而只有对每个团队和项目而言最适合的做法。简单来说,在项目开发中使用多个分支会带来额外的管理和维护开销,但是多个分支对于项目的团队合作、新功能开发和发布管理都是有一定好处的。不同的团队可以根据团队人员组成和意愿、项目的发布周期等因素选择最适合的策略,找到最适合团队的管理方式。本文将介绍三种常见的 Git 分支管理方式。单主干单主干的分支实践(Trunk-based development,TBD)在 SVN 中比较流行。Google 和 Facebook 都使用这种方式。trunk 是 SVN 中主干分支的名称,对应到 Git 中则是 master 分支。TBD 的特点是所有团队成员都在单个主干分支上进行开发。当需要发布时,先考虑使用标签(tag),即 tag 某个 commit 来作为发布的版本。如果仅靠 tag 不能满足要求,则从主干分支创建发布分支。bug 修复在主干分支中进行,再 cherry-pick 到发布分支。图 1 是 TBD 中分支流程的示意图。
图 1. TBD 中的分支流程的示意图

34498a2ecb42d2e747c14c3ac93c7790.png

由于所有开发人员都在同一个分支上工作,团队需要合理的分工和充分的沟通来保证不同开发人员的代码尽可能少的发生冲突。持续集成和自动化测试是必要的,用来及时发现主干分支中的 bug。因为主干分支是所有开发人员公用的,一个开发人员引入的 bug 可能对其他很多人造成影响。不过好处是由于分支所带来的额外开销非常小。开发人员不需要频繁在不同的分支之间切换。

GitHub flowGitHub flow 是 GitHub 所使用的一种简单的流程。该流程只使用两类分支,并依托于 GitHub 的 pull request 功能。在 GitHub flow 中,master 分支中包含稳定的代码。该分支已经或即将被部署到生产环境。master 分支的作用是提供一个稳定可靠的代码基础。任何开发人员都不允许把未测试或未审查的代码直接提交到 master 分支。对代码的任何修改,包括 bug 修复、hotfix、新功能开发等都在单独的分支中进行。不管是一行代码的小改动,还是需要几个星期开发的新功能,都采用同样的方式来管理。当需要进行修改时,从 master 分支创建一个新的分支。新分支的名称应该简单清晰地描述该分支的作用。所有相关的代码修改都在新分支中进行。开发人员可以自由地提交代码和 push 到远程仓库。当新分支中的代码全部完成之后,通过 GitHub 提交一个新的 pull request。团队中的其他人员会对代码进行审查,提出相关的修改意见。由持续集成服务器(如 Jenkins)对新分支进行自动化测试。当代码通过自动化测试和代码审查之后,该分支的代码被合并到 master 分支。再从 master 分支部署到生产环境。图 2 是 GitHub flow 分支流程的示意图。
图 2. Github flow 中的分支流程的示意图

b2b56319b373044de2aebf032e1cbc9a.png

GitHub flow 的好处在于非常简单实用。开发人员需要注意的事项非常少,很容易形成习惯。当需要进行任何修改时,总是从 master 分支创建新分支。完成之后通过 pull request 和相关的代码审查来合并回 master 分支。GitHub flow 要求项目有完善的自动化测试、持续集成和部署等相关的基础设施。每个新分支都需要测试和部署,如果这些不能自动化进行,会增加开发人员的工作量,导致无法有效地实施该流程。这种分支实践也要求团队有代码审查的相应流程。

git-flowgit-flow 应该是目前流传最广的 Git 分支管理实践。git-flow 围绕的核心概念是版本发布(release)。因此 git-flow 适用于有较长版本发布周期的项目。虽然目前推崇的做法是持续集成和随时发布。有的项目甚至可以一天发布很多次。随时发布对于 SaaS 服务类的项目来说是很适合的。不过仍然有很大数量的项目的发布周期是几个星期甚至几个月。较长的发布周期可能是由于非技术相关的因素造成的,比如人员限制、管理层决策和市场营销策略等。git-flow 流程中包含 5 类分支,分别是 master、develop、新功能分支(feature)、发布分支(release)和 hotfix。这些分支的作用和生命周期各不相同。master 分支中包含的是可以部署到生产环境中的代码,这一点和 GitHub flow 是相同的。develop 分支中包含的是下个版本需要发布的内容。从某种意义上来说,develop 是一个进行代码集成的分支。当 develop 分支集成了足够的新功能和 bug 修复代码之后,通过一个发布流程来完成新版本的发布。发布完成之后,develop 分支的代码会被合并到 master 分支中。其余三类分支的描述如表 1所示。这三类分支只在需要时从 develop 或 master 分支创建。在完成之后合并到 develop 或 master 分支。合并完成之后该分支被删除。这几类分支的名称应该遵循一定的命名规范,以方便开发人员识别。
表 1. git-flow 分支类型
分支类型命名规范创建自合并到说明
featurefeature/*developdevelop新功能
releaserelease/*developdevelop 和 master一次新版本的发布
hotfixhotfix/*masterdevelop 和 master生产环境中发现的紧急 bug 的修复
对于开发过程中的不同任务,需要在对应的分支上进行工作并正确地进行合并。每个任务开始前需要按照指定的步骤完成分支的创建。例如当需要开发一个新的功能时,基本的流程如下:
  • 从 develop 分支创建一个新的 feature 分支,如 feature/my-awesome-feature。
  • 在该 feature 分支上进行开发,提交代码,push 到远端仓库。
  • 当代码完成之后,合并到 develop 分支并删除当前 feature 分支。
在进行版本发布和 hotfix 时也有类似的流程。当需要发布新版本时,采用的是如下的流程:
  • 从 develop 分支创建一个新的 release 分支,如 release/1.4。
  • 把 release 分支部署到持续集成服务器上进行测试。测试包括自动化集成测试和手动的用户接受测试。
  • 对于测试中发现的问题,直接在 release 分支上提交修改。完成修改之后再次部署和测试。
  • 当 release 分支中的代码通过测试之后,把 release 分支合并到 develop 和 master 分支,并在 master 分支上添加相应的 tag。
因为 git-flow 相关的流程比较繁琐和难以记忆,在实践中一般使用辅助脚本来完成相关的工作。比如同样的开发新功能的任务,可以使用 git flow feature start my-awesome-feature 来完成新分支的创建,使用 git flow feature finish my-awesome-feature 来结束 feature 分支。辅助脚本会完成正确的分支创建、切换和合并等工作。

Maven JGit-Flow对于使用 Apache Maven 的项目来说,Atlassian 的 JGit-Flow 是一个更好的 git-flow 实现。JGit-Flow 是一个基于 JGit 的纯 Java 实现的 git-flow,并不需要安装额外的脚本,只需要作为 Maven 的插件添加到 Maven 项目中即可。JGit-Flow 同时可以替代 Maven release 插件来进行发布管理。JGit-Flow 会负责正确的设置不同分支中的 Maven 项目的 POM 文件中的版本,这对于 Maven 项目的构建和发布是很重要的。在 Maven 项目的 pom.xml 文件中添加代码清单1中的插件声明就可以使用 JGit-Flow。中包含的是 JGit-Flow 不同任务的配置。
清单 1. JGit-Flow 的 Maven 设置

external.atlassian.jgitflow jgitflow-maven-plugin 1.0-m5.1 release- RC true true true JGit-Flow 提供了很多配置选项,可以在 POM 文件中声明。这些配置项可以对不同的任务生效。常用的配置项如表2 所示。

表 2. JGit-Flow 的配置项
名称描述适用任务
flowInitContext配置不同类型的分支的名称全局
allowSnapshots是否允许存在 SNAPSHOT 类型的依赖
allowUntracked是否允许本地 Git 中存在未提交的内容
scmCommentPrefix 和 scmCommentSuffixJGit-Flow 会进行代码合并工作。通过这两个配置项来设置 JGit-Flow 进行代码提交时的消息的前缀和后缀全局
username 和 password进行 Git 认证时的用户名和密码,适用于 HTTPS 仓库全局
releaseBranchVersionSuffixrelease 分支中项目的 POM 文件版本号的后缀
developmentVersion下一个开发版本的版本号
releaseVersion发布版本的版本号
pushReleases是否把 release 分支 push 到远程仓库
goals当部署发布版本到 Maven 仓库时执行的目标release-finish,hotfix-finish
keepBranch当发布完成之后是否保留相应的分支release-finish,hotfix-finish
noDeploy是否启用部署到 Maven 仓库的功能release-finish,hotfix-finish
noReleaseBuild在完成发布时是否禁用 Maven 构建release-finish
noReleaseMerge在完成发布时是否把 release 分支合并回 develop 和 master 分支release-finish
noTag在完成发布时是否添加标签release-finish,hotfix-finish
squash在进行分支合并时,是否把多个 commit 合并成一个release-finish,hotfix-finish
featureName新特性分支的名称feature-start,feature-finish,feature-deploy
pushFeatures是否把特性分支 push 到远程仓库feature-start,feature-finish
noFeatureBuild在完成特性时是否禁用 Maven 构建feature-finish
noFeatureMerge在完成特性时是否把特性分支合并回 developfeature-finish
pushHotfixes在完成 hotfix 时是否把分支合并回 masterhotfix-finish
noHotfixBuild在完成 hotfix 时是否禁用 Maven 构建hotfix-finish
其余的配置项可以参考插件不同任务的文档。在启用了 JGit-Flow 之后,可以通过 mvn 运行 jgitflow:feature-start 和 jgitflow:feature-finish 来开始和结束新特性的开发。与版本发布和 hotfix 相关的命令分别是 jgitflow:release-start 和 jgitflow:release-finish 以及 jgitflow:hotfix-start 和 jgitflow:hotfix-finish。在运行命令之后,JGit-Flow 会完成相关的 Git 分支创建、合并、删除、添加 tag 等操作,不需要开发人员手动完成。每个分支的 pom.xml 中的版本号的格式并不相同。如 master 分支的版本号是标准的发布版本号,如 1.2.3;develop 分支中则是 SNAPSHOT 版本,比 master 分支的版本号要高,如 1.2.4-SNAPSHOT;release 分支可以通过配置来指定版本号的后缀,如 1.2.3-RC-SNAPSHOT;feature 分支可以通过配置来把 feature 分支名称作为后缀添加到版本号中,如 1.2.3-my-awesome-feature-SNAPSHOT;hotfix 分支的版本号基于 master 分支的版本号,如 1.2.3.1 是对于 1.2.3 版本的第一个 hotfix。当使用 jgitflow:release-finish 完成一个 release 分支时,develop 分支的版本号会被自动更新成下一个小版本,如从 1.2.3 到 1.2.4。当需要手动修改版本号时,可以使用 Versions 插件,如 mvn versions:set -DnewVersion=2.0.0-SNAPSHOT。持续集成

由于 JGit-Flow 是纯 Java 的 Maven 插件实现,可以很容易的与常用的持续集成服务器进行集成。不过在与 Atlassian 的 Bamboo 集成时,有几个细节需要注意。首先是 Bamboo 在进行构建的时候,使用的是一个虚拟的 Git 仓库,其仓库地址是一个不存在的文件系统路径。因此需要在 JGit-Flow 的配置中手动设置 Git 仓库的地址,保证 Git 操作可以正确执行,如代码清单2所示。

清单 2. 手动设置 JGit-Flow 的 Git 仓库地址

[Git url] true另外在开始新的 release 之前,需要确保前一个发布分支已经被删除。JGit-Flow 在默认情况下会自动在发布完成之后,删除对应的 Git 分支。但是可能本地仓库中还保留有之前的发布分支,这会导致新的 release-start 任务执行失败。一种解决方式是每次都重新 checkout 新的仓库,这样可以保证不会出现已经在远程被删除的分支。不过可能会增加构建的时间。另外一种解决方式是通过 Git 命令来删除本地分支,如代码清单3所示。Git 分支合并冲突处理当把发布分支合并到 develop 时,可能会出现冲突。因为在发布分支中有与 bug fix 相关的改动,在 develop 分支中有可能修改相同的文件。当有冲突时,直接运行 JGit-Flow 的 release-finish 任务会出错。这个时候需要开发人员手动把发布分支合并到 develop 分支,并解决相应的冲突。然后再次运行 release-finish 任务即可。

选择合适的实践每个开发团队都应该根据团队自身和项目的特点来选择最适合的分支实践。首先是项目的版本发布周期。如果发布周期较长,则 git-flow 是最好的选择。git-flow 可以很好地解决新功能开发、版本发布、生产系统维护等问题;如果发布周期较短,则 TBD 和 GitHub flow 都是不错的选择。GitHub flow 的特色在于集成了 pull request 和代码审查。如果项目已经使用 GitHub,则 GitHub flow 是最佳的选择。GitHub flow 和 TBD 对持续集成和自动化测试等基础设施有比较高的要求。如果相关的基础设施不完善,则不建议使用。

小结Git 作为目前最流行的源代码管理工具,已经被很多开发人员所熟悉和使用。在基于 Git 的团队开发中,Git 分支的作用非常重要,可以让团队的不同成员同时在多个相对独立的特性上工作。本文对目前流行的 3 种 Git 分支管理实践做了介绍,并着重介绍了 git-flow 以及与之相关的 Maven JGit-Flow 插件。7392406487446986a8c8437317af08b7.gif

分布式中采用Logback的MDC机制与AOP切面结合串联日志

三个方案解决Elasticsearch深度翻页问题

大型系统的发布部署方案(图文)

分布式系统中Redis为什么那么重要?

彻底搞清分库分表(垂直分库,垂直分表,水平分库,水平分表)

小白也能学会的RAID磁盘冗余阵列教程

ecccb24cd5640133e9c4b7e2ee143ff4.png欢迎分享转发,有帮助的话点个“在看”2ce2e735494ce2f85aa16deb642b6cad.gif



推荐阅读
  • 用Vue实现的Demo商品管理效果图及实现代码
    本文介绍了一个使用Vue实现的Demo商品管理的效果图及实现代码。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 一、路由首先需要配置路由,就是点击good组件进入goodDetail组件配置路由如下{path:goodDetail,component:goodDetail}同时在good组件中写入如下点击事件,路由中加入 ... [详细]
  • 开发笔记:Python之路第一篇:初识Python
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Python之路第一篇:初识Python相关的知识,希望对你有一定的参考价值。Python简介& ... [详细]
  • Hello.js 是一个用于连接OAuth2服务的JavascriptRESTFULAPI库,如Go ... [详细]
  • React 小白初入门
    推荐学习:React官方文档:https:react.docschina.orgReact菜鸟教程:https:www.runoob.c ... [详细]
  • OAuth2.0指南
    引言OAuth2.0是一种应用之间彼此访问数据的开源授权协议。比如,一个游戏应用可以访问Facebook的用户数据,或者一个基于地理的应用可以访问Foursquare的用户数据等。 ... [详细]
  • 双十一在家学用 Git
    对于所有的开发者来说,掌握一门代码版本控制系统都是必须的,无论是自己做项目,团队合作,工作中的合作,都离不开版 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • x86 linux的进程调度,x86体系结构下Linux2.6.26的进程调度和切换
    进程调度相关数据结构task_structtask_struct是进程在内核中对应的数据结构,它标识了进程的状态等各项信息。其中有一项thread_struct结构的 ... [详细]
  • struts2重点——ValueStack和OGNL
    一、值栈(ValueStack)1.实现类:OGNLValueStack2.对象栈:CompoundRoot( ... [详细]
author-avatar
爱做梦的蓝梦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有