Git 分支管理以及日常情况处理方案

995 阅读6分钟

这篇文章分享 Git 分支管理以及一些日常情况处理方案,目的是设立 Git 规范让项目 Git 操作一眼明了,也为大家在处理异常时提供一些方案。

分支管理策略是一个见仁见智的问题,没有绝对最好的,只有最适合自己项目的。

并且规则是灵活的,可以根据不同的项目来做衍生的规范。

分支命名

分支的命名基于以下的准则:

  1. 一眼明了
  2. 减少生命消耗

基于上面的两个准则设计的分支命名如下:

分支名称
master主分支
releae-*预发布分支
fix-*紧急修复分支
pm-*产品需求分支 project manager 缩写
pd-*技术需求分支 project developer 缩写

master 分支

master为主分支,用于部署到正式环境。并且master分支是被分支保护的,只能merge request合并,经过项目负责人review才能合并;

release 分支

release为预发布分支,用于部署到预发布环境;release分支从master切出,合并需求分支;

如果release分支测试出问题,建议在需求分支上修改验证后,再合并到release分支;

fix 分支

fix 分支为修复分支,不采用业内常用的hotfix命名,是因为fix命名也可直观并且节省时间;

fix分支从master切出,mergemaster 后删除源分支

pm pd 分支

pmpd分支为开发分支,有业内feature分支延伸,不要问为何不用feature命名,问就是因为节省时间,一眼明了;

pm,pd分支都是从master分支上切出,用于部署开发,测试环境;

其他

分支命名仅能使用 .-_ 特殊符号;

因为当我们在做 CI或者webhook服务时,有可能会用到分支名来做文件夹等,为了避免系统文件夹不支持特殊符号导致出错,所以限定可以使用的符号;

不建议用 / 符号的原因是因为,在linux/代表着路径,如果存在使用分支名创建文件夹的时候会导致创建二级目录;并且在webhook中传给钩子服务中的分支命名是 repo/projectName/branchName,如此不能确认repo/projectName不是固定的情况下,会导致分支名取错;

公司项目的分支命名

前面也说到要找到一个适合自己的分支管理;在公司的一个项目中,有自己的一套分支管理;

这项目是有其特殊性的,具体表现在多业务项目多版本的集合在一起,需求分域名提测;

简单提一句之所以做需求分域名提测,是因为当测试环境只有一个的时候,需要排队使用测试环境的测试;

针对这种多业务多版本的开发,我们可以在分支命名的规范上再做修改,分支命名为:

分支名备注
master主分支
pm-project-version-feature产品需求分支
pd-feature-date技术需求分支
fix-*修复分支

产品需求分支 我们加了 project 的区分,project 命名尽量使用缩写,减少生命消耗,如腾讯项目1.1版本微信功能,我们可以起个名字 pm-tx-1.1-wechat;

同时这个项目是没有release分支的,主要是因为该项目有钩子服务帮忙在机器上,部署nginx服务;

image

如此,我们仅需要在项目中nginx配置文件中配置好各环境接口地址,部署到机器上,即可同时将一份代码同时应用到不同环境,即时后端没有部署预发布环境等;

FAQ

1. 代码被回滚后如何操作

通常会有的情况是代码被merge上线之后发现有问题,解决的问题的最快方法是在业务机器上回滚代码;

如果我们不是使用发release包的方式部署代码,并且仓库master有CI自动部署的操作,最快的方式是回滚master代码;

gitlab上代码被merge之后是有提供一键回滚操作的,使用的是revertrevert表示用一次新的提交重做某次提交,如下例子1表示revert操作后的结果;

例子1:

master a -- b      c -- d(revert c)
             \     |
dev-c         b -- c 

理想情况下,当我们排查好问题后,会在原来的开发分支或者新建一个修复分支修改对应代码后,再pull request master

但是我们会发现,无论从master切新的分支进行修复,或者更新 masterdev-c 分支(不更新会有冲突),都会发现c的代码都被回滚了,那么如何把c的代码再加入到工作区呢?

我们只需要在开发分支中,把 master回滚操作再回滚,就可以得到c的代码了

revert操作结果如下:

master a -- b      c -- d(revert c)     --     e
             \     |     \                     |
dev-c         b -- c      d(c 的代码没有了) --  e(revert d后得到c代码 && fix something)

具体操作为

git checkout dev-c
git merge master
git revert -n commitID // 回滚回滚操作,并且不提交
git add . 
git commit -m 'xxxx'
git push orign dev-c

当然回滚的还有其他方法,这里只介绍常规的做法;

PS: 用reset方法是不行的,这是另一个话题了;

2. 多人开发同一版本如何进行分支管理

在多人同时开发的统一的版本中,会出现同时开发A、B、C等多个需求,并且要求需求同时上线;

因为是用一天上线,开发人员可能会乖乖地给这些需求建一个统一的分支1.0.0,然后把所有的需求代码都提交到这个分支上;

但是现实是到了发版的日子,已经通过测试的需求,会出现种种情况:

  1. 比如B需求不上线了,这么就要把B需求相关的代码注释,需求改动小还好说,需求大涉及的代码块太多,耗时耗力后果不堪设想;
  2. 又或者A、B、C需求同时上线了,B要回滚,那么就只能把1.0.0分支都回滚,然后再注释,再上线...

如果测试和发版不是同一个release包,那么操作操作已经测试通过的代码,是危险的操作

为了避免上面种种情况,我们是建议每个需求都分配不同的分支,如 pm-1.0-a,pm-1.0-b,pm-1.0-c

image

这样做的好处是我们每个需求都可以自由地组合,比如上面的B需求不上线,我们可以把a,c的需求合到1.0.0分支,避免操作代码,更加灵活组合;