Git 的原理与使用(下)(一)+https://developer.aliyun.com/article/1521999?spm=a2c6h.13148508.setting.14.439a4f0eYTiYcj
3.不同分支下多人协作(一般情况
一般情况下,如果有多需求需要多人同时进行开发,是不会在一个分支上进行多人开发的,而是每一个需求或一个功能点就要创建一个分支。
现在同时有两个需求需要你和你的小伙伴进行开发,那么你们俩便可以各自创建一个远程分支来完成自己的工作。
根据功能点创建远程分支有两种方法:
1、直接在远程仓库的gitee上创建分支。【推荐】
直接在远程仓库上基于master创建分支,而远程master就是最新、最全、最稳定的代码,能够保证基于它创建出的其它分支也是最新最全最稳定的。
2、在本地创建分支,然后将本地的分支push到远程仓库下。【本文演示】
- 本地的master无法保证是最新的,因为有可能其他的协作者刚好push了新的代码到远程。
- 要在本地创建分支,必须先让本地master:pull。
本文对上面提到的第二种方法进行演示:
命令
git branch -a
可以查看最近一次pull
时本地和远程所有分支的情况。(注意它并不会自动更新本地的远程分支列表,即在pull
之后有其他人在远程仓库修改了远程分支,在本地是看不到的。)
通过 git push origin feature-1
命令把本地仓库feature-1分支下的内容推送给远程仓库feature-1分支下的内容(远程仓库的feature-1分支自动创建):
查看gitee远程仓库发现feature-1分支已创建,并且feature-1下有刚才新增的func1文件。
对于另外一位开发者来说,操作步骤和第一位开发者是一样的:
先对master进行git pull 使本地master最新。
git branch -b feature-2创建并切换到分支feature-2。
在feature-2分支下新建func2文件,并将func2文件git push origin feature-2到远程仓库。
远程仓库中可以看到feature-2分支,且feature-2分支下有文件func2。
二人的操作是彼此独立的。在本地,你看不见他新建的文档,他看不见你新建的文档。并且push的是各自的分支,不会产生任何冲突,二人互不影响。
正常情况下,你俩就可以在自己的分支上进行专业的开发了。
但天有不测风云,你的小伙伴突然生病了,但需求还没开发完,需要你帮他继续开发,于是他便把
feature-2分支名告诉你了。这时你就需要在自己的机器上切换到feature-2分支帮忙继续开发。
此时可以执行git pull
(短命令)更新远程分支列表:
对于git pull(短命令)有两个作用:
拉取分支内的内容。如把origin/dev中的文件拉取到本地的dev中。这个情况必须提前建立好dev和origin/dev之间的连接才能有效。
拉取远程仓库的内容。此时和分支是否建立联系没有关系,可以直接执行git pull来更新本地的远程仓库列表。
更新完本地记录的远程仓库列表后,在本地也创建并切换到分支feature-2:
git checkout -b feature-2 origin/feature-2 # 自动与远程仓库的feature-2分支关联
关联并切换成功后,便可以在本地的feature-2分支上看见开发者2提交的function2文件了。
接着就可以帮开发者2小伙伴进行开发,开发完毕后push到远程的origin/feature-2中。
这时,你的小伙伴已经休养地差不多,可以继续进行自己的开发工作了,那么他回到岗位首先要获取到你帮他开发的内容,然后再接着你的代码继续开发。
这时直接pull是无效的,原因是之前远程仓库的feature-2分支是通过git push origin feature-2命令创建的,但这个方式并不会将远程分支feature-2和本地分支feature-2自动关联。因此,小伙伴没有指定本地feature-2分支与远程origin/feature-2分支的链接,。
根据提示,设置feature-2和origin/feature-2的链接即可:
git branch --set-upstream-to=origin/feature-2 feature-2
目前,小伙伴的本地代码就和远端保持严格一致了。你和你的小伙伴可以继续在不同的分支下进行协同开发了。各自功能开发完毕后,不要忘记我们需要将代码合并到master中才算真正意义上的开发完毕。
Pull Request流程演示
开发者1先提交PR(feature-1 -> master),审查通过后master与feature-1成功合并。
开发者2提交PR时,有几点要注意:
feature-2可能会与feature-1存在conflict,而feature-1已经被合并入master,因此feature-2可能与master存在conflict。
如果feature-2与master之间存在conflict,那解决冲突是在master上,不安全。
正确的做法是:先在feature-2中合并master,有conflict在feature-2上解决。然后再提PR,此时master和feature-2之间就不会有冲突了。(上面提到过)
由于feature-1已经merge进了master,在本地执行feature-2中合并master的操作时不要忘了先在master上pull一下,保证master最新。
这就是多人协作的工作模式,一旦熟悉了,就非常简单。
补充:本地 git branch -a 依然能看到删除的远程分支的解决办法
当前我们已经删除了远程的几个分支,使用 git branch -a 命令查看本地分支和远程分支列表时却发现,很多在远程仓库已经删除的分支依然能看到。例如:
使用命令
git remote show origin
可以查看remote地址、远程分支还有本地分支与之相对应关系等信息。
此时我们可以看到那些远程仓库已经不存在的分支。
提示信息说明了使用 git remote prune
就能移除stale的远端分支(即在本地git branch -a
不被显示)。根据提示,使用 git remote prune origin
命令:
这样就删除了那些远程仓库不存在的分支:
九、企业级开发模型
1.讲个故事
我们知道,⼀个软件从零开始到最终交付,大概包括以下几个阶段:规划、编码、构建、测试、发布、部署和维护,即【开发->测试->发布上线】。
最初,程序比较简单,工作量不大,程序员⼀个人可以完成所有阶段的工作。但随着软件产业的日益发展壮大,软件的规模也在逐渐变得庞大。软件的复杂度不断攀升,⼀个人已经hold不住了,就开始出现了精细化分工。如下图所示:
但在传统的 IT 组织下,开发团队(Dev)和运维团队(Ops)之间诉求不同:
开发团队(尤其是敏捷团队)是追求「变化」的。
运维团队是追求「稳定」的。
双方往往存在“利益的冲突”。比如,精益和敏捷的团队把持续交付(即 CD)作为目标,而运维团队则为了线上的稳定而强调变更控制。部门墙由此建立起来,这当然不利于IT价值的最大化。
为了弥合开发和运维之间的鸿沟,需要在文化、工具和实践方面的系列变革⸺DevOps由此诞生。
DevOps(Development 和 Operations 的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。在DevOps的软件开发过程包含计划、编码、构建、测试、预发布、发布、运维、监控。
由此可见DevOps的强大。
讲了这么多,这到底和Git有什么关系呢?
举⼀个很简单的例子就能说明问题:一个软件的迭代,在我们开发人员看来,说白了就是对代码进行迭代,那么就需要对代码进行管理;如何管理我们的代码呢,那使用的不就是Git(分布式版本控制系统)了!所以Git对于我们开发人员来说,其重要性就不言而喻了。
2.系统开发环境
言归正传,对于开发人员来说,在系统开发过程中最常用的几个环境必须要了解一下:
开发环境:开发环境是程序猿们专门用于日常开发的服务器。为了开发调试方便,一般打开全部错误报告和测试工具,是最基础的环境。
测试环境:一个程序在测试环境工作不正常,那么肯定不能把它发布到生产机上。该环境是开发环境到生产环境的过渡环境。
预发布环境:该环境是为避免因测试环境和线上环境的差异等带来的缺陷漏测而设立的一套环境。其配置等基本和生产环境一致,目的是能让我们发正式环境时更有把握!所以预发布环境是你的产品质量最后一道防线,因为下一步你的项目就要上线了。要注意预发布环境服务器不在线上集成服务器范围之内,为单独的一些机器。
生产环境:是指正式提供对外服务的线上环境,例如我们目前在移动端或PC端能访问到的APP都是生产环境。(代码稳定+环境配置稳定)
这几个环境也可以说是系统开发的三个重要阶段:开发->测试->上线。一张图总结:
各个环境之间是隔离的。对于规模稍大的公司来说,可不止这么几个环境,比如项目正式上线前还存在仿真/灰度环境(灰度策略,地域灰度:让小范围一部分人先使用新产品,如果这一小部分人没有问题再逐渐推送到全部人;人群灰度:如先对老年人开放使用等),再比如还存在多套测试环境,以满足不同版本上线前测试的需要。
一个项目的开始从设计开始,而一个项目的成功则从测试开始。一套良好的测试体系可以将系统中绝大部分的致命Bug解决在系统上线之前。
测试系统的完善和成熟也是衡量一个软件企业整体水平的重要指标之一,测试往往被忽视,但是它却是软件质量的最终保障,乃至项目能否成功的重要因素。
3.Git分支设计规范
有了对「环境」的概念后,那么对于开发人员来说,一般会针对不同的环境来设计分支,举一个例子:
注:以上表格中的分支和环境的搭配仅是常用的一种,可视情况而定不同的策略。
master分支
master为主分支,该分支为只读且唯一分支。用于部署到正式发布环境,一般由合并release分支得到。(测试人员测完之后认为release分支没有问题了,就可以和master进行合并。)
主分支作为稳定的唯一代码库,任何情况下不允许直接在master分支上修改代码。
产品的功能全部实现后,最终在master分支对外发布,另外所有在master分支的推送应该打标签(tag)做记录,方便追溯。
master分支不可删除。
feature分支
feature 分支通常为新功能或新特性开发分支,以 develop 分支为基础创建 feature 分支。
命名以 feature/ 开头,建议的命名规则: feature/user_createtime_feature 。
新特性或新功能开发完成后,开发人员需合到 develop 分支。
一旦该需求发布上线,便将其删除。
develop分支
develop 为开发分支,基于master分支创建的只读且唯一分支,始终保持最新完成以及 bug 修复后的代码。可部署到开发环境对应集群。
可根据需求大小程度确定是由分支合并,还是直接在上面开发(非常不建议,应该在feature上开发完了之后,再把代码合并到develop)。
release分支
release 为预发布分支,基于本次上线所有的 feature 分支合并到 develop 分支之后,基于 develop 分支创建。可以部署到测试或预发布集群。
命名以 release/ 开头,建议的命名规则: release/version_publishtime 。
release 分支主要用于提交给测试人员进行功能测试。发布提测阶段,会以 release 分支代码为基准进行提测。
如果在 release 分支测试出问题,需要回归验证 develop 分支看否存在此问题。
release 分支属于临时分支,产品上线后可选删除。
hotfix 分支
hotfix 分支为线上 bug 修复分支或叫补丁分支,主要用于对线上的版本进行 bug 修复。当线上出现紧急问题需要马上修复时,需要基于 master 分支创建 hotfix 分支。
命名以 hotfix/ 开头,建议的命名规则: hotfix/user_createtime_hotfix
当问题修复完成后,需要合并到 master 分支和 develop 分支并推送远程。一旦修复上线,便将其删除。
一张图总结:
以上所讲解的,就是企业级常用的一种Git分支设计规范:GitFlow模型。
但要说的是,该模型并不是适用于所有的团队、所有的环境和所有的文化。
如果你采用了持续交付(CD),你会想要一些能够尽可能简化交付过程的东西。有些人喜欢基于主干的开发模式,喜欢使用特性标志。然而,从测试的角度来看,这些反而会吓一跳。
关键在于站在你的团队或项目的角度思考:这种分支模型可以帮助你们解决哪些问题?它会带来哪些问题?这种模式为哪种开发提供更好的支持?你们想要鼓励这种行为吗?你选择的分支模型最终都是为了让人们更容易地进行软件协作开发。因此,分支模型需要考虑到使用者的需求,而不是盲目听信某些所谓的“成功的分支模型”。
所以对于不同公司,规范是会有些许差异,但万变不离其宗,一切的目的是为了效率与稳定。
4.企业级项目管理实战
准备工作
DevOps研发平台
Gitee企业版免费版
企业名称可随意填写一个测试名称,只要能通过即可。注意,多人协作开发,需要将多人账号拉入一个企业下才行。如何添加成员后面会跟大家讲解。
创建项目
注:
- 创建的仓库可以关联到某个项目中被管理
添加成员
1、添加企业成员
申请后,需要负责人审批通过。
2、添加项目成员
3、添加仓库开发人员
开发场景-基于gitflow模型的实践
新需求加入
现有一个订单管理的新需求需要开发,首先可以基于 develop 分支创建一个:feature/xxxxx_20231012
分支。
1、需求在 feature/xxxxx_20231012 分支开发完毕,这时研发人员可以将代码合并到develop 分支,将其部署在开发环境的服务器中,方便开发人员进行测试和调试。
- 开发者在 feature 分支下发起请求评审。
- 审查员审查代码。
- 审查通过,合并分支。
- 合并成功,查看结果
2、在develop
下开发人员自测通过后,先确定下develop
不存在未测试完毕的需求,然后研发人员可基于develop
分支创建一个release/xxx
分支出来,可交由测试人员进行测试。
3、测试人员测试 release 通过后(包含测试环境和预发布环境的测试),就可将代码合并入master
。
4、测试人员在 master (正式环境) 测试通过后,便可删除 feature/xxx 分支。
修复测试环境Bug
在develop测试出现了Bug,建议大家直接在feature分支上进行修复。修复后的提测上线流程与新需求加入的流程一致。
修改预发布环境Bug
在测试出现了Bug,首先要回归下分支是否同样存在这个问题。如果存在,修复流程与修复测试环境Bug流程一致;如果不存在,这种可能性比较少,大部分是数据兼容问题,环境配置问题等。
修改正式环境Bug
在 master 测试出现了Bug,首先要回归下 release 和 develop 分支是否同样存在这个问题。如果存在,修复流程 与 修复测试环境 Bug流程一致。如果不存在,这种可能性也比较少,大部分是数据兼容问题,环境配置问题等。
如果存在,修复流程 与 修复测试环境 Bug流程一致;如果不存在,这种可能性也比较少,大部分是数据兼容问题,环境配置问题等。
紧急修复正式环境Bug
需求在测试环节未测试出 Bug,上线运行一段时候后出现了 Bug,需要紧急修复的。有的企业面对紧急修复时,支持不进行测试环境的验证,但还是建议验证下预发布环境。可基于 master 创建 hotfix/xxx 分支,修复完毕后发布到 master 验证,验证完毕后,将master 代码合并到 develop 分支,同时删掉 hotfix/xxx 分支。
拓展阅读
其他的DevOps研发平台
腾讯coding
阿里云效
拓展实践
阿里飞流flow分支模型,及项目版本管理实践:项目版本管理的最佳实践:飞流Flow(阿里AoneFlow)篇-CSDN博客
**小结
本篇涉及的部分git命令:
git tag [name] [commit ID]:给commit打标签
git tag:查看当前所有存在的标签
git tag -a [name] -m "XXX" [commit_id]:给新创建的标签添加标签说明
git show [tag名称]:查看这个tag对应的详细信息
git tag -d <tag名称>:删除标签
git push origin <tagname>:推送某个标签到远程
git push origin --tags:一次性把本地所有标签全部推送到远端
git push origin :<tag名称>:本地已删除某标签,要让远程也删除该标签
git branch -vv:查看本地仓库分支和远程仓库分支对应关系
git branch --set-upstream-to=origin/<远程分支名> <本地分支名>:手动给远程分支和本地分支建立关联
git branch -a:查看最近一次pull时本地和远程所有分支的情况