记得之前也写过一篇类似的文章,来到我东后感觉不够详尽,很多流程还是太局限了。大厂的开发流程还是比较规范的。如果你来不及学习长篇大论的 git 文档,这篇文章够你入职时用一段时间了。
一、开发分支模型分类
目前所在部门使用是主要是四种:dev(开发)、test(测试)、uat(预发)、release(生产)
小公司可能就一个 dev、一个 master 就搞定了,测试都是开发人员自己来🤣。
二、开发主体流程
- 需求评审
- 开发排期
- 编码开发
- 冒烟测试(自检验)
- 冒烟通过,提交测试,合并代码到测试分支,部署测试环境
- 测试环境测试,开发修 bug
- 测试完成,提交预发,合并代码到预发分支,部署预发环境
- 预发环境测试,开发修 bug(修完的 bug 要重新走测试再走预发,这个下面会解释)
- 测试完成,产品验收
- 验收完成,提交生产,合并代码到生产分支,部署生产环境
- 生产运营(客户)验收
- 验收完成,结项
三、具体操作
1. 拉取代码
一般都会在本地默认创建一个 master 分支
shell
git clone https://code.xxx.com/xxx/xxx.git
2. 初次开发需求前,要先拉取生产/预发分支,然后基于这个分支之上,创建自己的特性分支进行开发
shell
git fetch origin release:release
git checkout release
git checkout -b feat-0131-jie
此时,在你本地已经有了一个 release 分支对应着远程仓库的 release 分支,还有一个内容基于 release 分支的特性分支,之后便可以在这个特性分支上进行需求开发了。
注意1:分支名称是有规范和含义的,不能乱取。
推荐格式:分支责任-需求日期/需求号-开发人姓名
,一般按部门规范来,常见的有以下几种。
js
- feat:新功能
- fix:修补bug
- doc:文档
- refactor:重构(即不是新增功能,也不是修改bug的代码变动)
- test:测试
- chore:构建过程或辅助工具的变动
注意2:为啥拉取的是生产/预发分支
之所以要拉取 release/uat 分支而不是拉取 dev/test,是因为后者可能包含着一些其他成员还未上线或者可能有 bug 的需求代码,这些代码没有通过验证,如果被你给拉取了,然后又基于此进行新的需求开发,那当你需求开发完成,而其他成员的需求还没上线,你将会把这些未验证的代码一起发送到 uat/release 上,导致一系列问题。
3. 需求开发完成,提交&合并代码
首先先在本地把新的改动提交,提交描述的格式可以参考着分支名的格式
- 如果是新需求的提交,可以写成 "feat: 需求0131-新增账期"
- 如果是 bug 修复,可以写成 "fix: 禅道3387-重复请求"
shell
git add .
git commit -m "提交描述"
此时,本地当前分支已经记录了你的提交记录,接下来进行代码合并了
在代码合并之前,我们先要梳理一下我们应该如何对分支进行管理(非常重要!)
-
首先,我们需要认知到的是,每一个分支应该只对应一个功能,例如当我们开发需求 01 时,那么就创建一个
feat-01-jie
分支进行开发;开发需求 02 时,就另外创建一个feat-02-jie
分支进行开发;修改生产环境的某个 bug 时,就创建fix-jie-3378
进行开发,等等。这样做的目的是,能够把不同的功能/需求/修改分离开来。想象一下这样一个场景,如果有某些紧急的需求是需要提前上线的,而此时你的分支里既包含了这些紧急的需求,又包含了其他未开发好的需求,那么这两种需求就不能拆开来分别进行提测和上线了。
-
其次,在合并代码时,我们要将四种分支模型(dev、test、uat、release)作为参照物,而不是把关注点放在自己的分支上。比如我们要在 dev 上调试,那就需要把自己的分支合并到 dev 分支上;如果我们需要提测,则把自己的分支合并到 test 分支上,以此类推。
即,我们要关注到,这四个环境的分支上,会有什么内容,会新增什么内容。切记不能反过来将这四个分支合并到自己的代码上!! 如果其他成员将自己的代码也提交到 dev 分支上,但是这个代码是没有通过验证的,此时你将 dev 往自己的分支上合,那之后的提测、上预发、生产则很大概率会出问题。所以一定要保持自己的分支是干净的!
接下来介绍合并代码的方式:
第一种:线上合并,也是推荐的规范操作
shell
git push origin feat-0131-jie
先接着上面的提交步骤,将自己的分支推送到远程仓库。
然后在线上代码仓库中,申请将自己的分支合并到 xx 分支(具体是哪个分支就根据你当前的开发进度来,如 test),然后在线上解决冲突。如果有权限就自己通过了,如果没有就得找 mt 啥的
第二种,本地合并(前提你要有对应环境分支 push 的权限)
shell
## 先切换到你要提交的环境分支上,如果本地还没有就先拉取下来
git fetch origin test:test
git checkout test
## 然后将自己的分支合并到环境分支上(在编辑器解决冲突)
git merge feat-0131-jie
## 最后将环境分支推送到远程仓库
git push origin test
shell
## 先切换到你要提交的环境分支上,如果本地已有该分支,则需要先拉取最新代码
git checkout test
git pull origin test
## 然后将自己的分支合并到环境分支上(在编辑器解决冲突)
git merge feat-0131-jie
## 最后将环境分支推送到远程仓库
git push origin test
两种方式有何区别?为什么推荐第一种?
这是因为在团队协作开发的过程中,将合并操作限制在线上环境有以下几个好处:
- 避免本地合并冲突:如果多个开发人员同时在本地进行合并操作,并且对同一段代码进行了修改,可能会导致冲突。将合并操作集中在线上环境可以减少此类冲突的发生,因为不同开发人员的修改会先在线上进行合并,然后再通过更新拉取到本地。
- 更好的代码审查:将合并操作放在线上环境可以方便其他开发人员进行代码审查。其他人员可以在线上查看合并请求的代码变动、注释和讨论,并提供反馈和建议。这样可以确保代码的质量和可维护性。
- 提高可追溯性和可回滚性:将合并操作记录在线上可以更容易地进行版本控制和管理。如果出现问题或需要回滚到之前的版本,可以更轻松地找到相关的合并记录并进行处理。
当然,并非所有情况都适用于第一种方式。在某些特定情况下,例如个人项目或小团队内部开发,允许本地合并也是可以的。但在大多数团队协作的场景中,将合并操作集中在线上环境具有更多优势。
4. 验收完成,删除分支
当我们这一版的需求完成后,本地肯定已经留有很多分支了,这些分支对于之后的开发已经意义不大了,留下来只会看着一团糟。
shell
git branch -d <分支名>
## 如果要强制删除分支(即使分支上有未合并的修改)
git branch -D <分支名>
四、一些小问题
1. 前面提到,预发环境修完的 bug 要重新走测试再走预发,为什么呢?
预生产环境是介于测试和生产环境之间的一个环境,它的目的是模拟生产环境并进行更真实的测试。 它是一个重要的测试环境,需要保持稳定和可靠。通过对修复的bug再次提交到测试环境测试,可以确保预生产环境中的软件版本是经过验证的,并且没有明显的问题。
当然,也不是非要这么做不可,紧急情况下,也可以选择直接发到预生产重新测试,只要你保证你的代码 99% 没问题了。
2. 代码合并错误,并且已经推送到远程分支,如何解决?
假设是在本地合并,本来要把特性分支合并到 uat 分支,结果不小心合到了 release 分支(绝对不是我自己的案例,绝对不是。。。虽然好在最后同事本地有我提交前的版本,事情就简单很多了)
首先切换到特性分支合并到的错误分支,比如是 release
shell
git checkout release
然后查看最近的合并信息
shell
git log --merges
撤销合并
shell
git revert -m 1 <merge commit ID>
- 这里的 merge commit ID 就是上一步查询出来的 ID 或者 ID 的前几个字符
最后,撤销远程仓库的推送
shell
git push -f origin release
- 这个命令会强制推送本地撤销合并后的 release 分支到远程仓库,覆盖掉远程仓库上的内容。(即,得通过一个新的提交来"撤销"上一次的提交,本质上是覆盖)