3、代码管理:Git仓库搭建、分支策略(Git Flow)、代码拉取与版本锁定
代码管理这事儿,说大不大,说小不小。我见过不少团队,业务逻辑写得挺溜,结果一到多人协作就乱成一锅粥——覆盖代码、丢失提交、上线版本对不上……说白了,就是没把代码管理当回事。
这一章,咱们就聊聊验证服务部署里,代码管理到底该怎么搞。我会从仓库搭建、分支策略、到版本锁定,一条线讲清楚。
3.1 Git仓库搭建:别小看这一步
仓库搭建听起来简单,git init 一下不就完了?嗯,但生产环境里,我建议你至少要考虑三个问题:权限、备份、和命名规范。
3.1.1 仓库选型
我个人习惯用 GitLab 自建,或者用 Gitee / GitHub 的私有仓库。选哪个不重要,重要的是——权限粒度要够细。验证服务涉及敏感配置和部署脚本,不能谁都能 push 到 master。
| 平台 | 优点 | 缺点 |
|---|---|---|
| GitLab 自建 | 权限控制灵活、CI/CD 集成好 | 需要维护服务器 |
| GitHub | 生态好、社区活跃 | 私有仓库有数量限制(免费版) |
| Gitee | 国内速度快、免费私有库 | 部分高级功能收费 |
3.1.2 仓库结构建议
我建议一个验证服务项目,至少拆成两个仓库:
- 验证服务代码库:放业务代码、测试用例、部署脚本。
- 配置与版本库:放环境配置、版本锁文件、密钥模板(注意:密钥本身不要入库)。
为什么要拆?我在项目中遇到过,配置文件和代码混在一起,每次改个数据库地址都要走一遍完整的代码审查流程,效率极低。拆开之后,配置变更可以单独走审批,灵活多了。
3.2 分支策略:Git Flow 还是其他?
分支策略这东西,没有银弹。但如果你问我,验证服务部署最适合什么?我会说——Git Flow 的简化版。
为什么不是标准的 Git Flow?标准版太重了,有 hotfix、release、develop、feature 五六个分支,小团队根本玩不转。我踩过这个坑,有一次为了修一个线上 bug,在 hotfix 和 release 之间来回合并,最后搞出了冲突,差点耽误上线。
3.2.1 我推荐的分支模型
说白了,就三个核心分支:
- master:只接受来自 release 或 hotfix 的合并。永远保持可部署状态。
- develop:日常开发的主战场。feature 分支从这里拉,合并回这里。
- release/x.y.z:从 develop 拉出,只做 bug 修复和版本号更新,合并到 master 和 develop。
再加上两个辅助分支:
- feature/xxx:从 develop 拉,开发完合并回 develop。
- hotfix/xxx:从 master 拉,修完合并回 master 和 develop。
核心原则: master 永远是稳定的。任何未经测试的代码,都不允许直接推到 master。
3.2.2 分支命名规范
没有规范的分支名,就是灾难。我见过有人用 "fix-bug"、"test" 这种名字,过两周自己都忘了是干嘛的。
我建议这样命名:
feature/<模块名>-<简短描述>
release/<版本号>
hotfix/<问题编号>-<简短描述>
举个例子:
feature/deploy-script-optimize
release/1.2.0
hotfix/INC-3421-fix-timeout
3.3 代码拉取与版本锁定
代码拉取,听起来就是 git clone 和 git pull。但验证服务部署里,这里有个关键点——版本锁定。
你想想看,如果部署脚本里写的是 git pull 拉最新代码,那每次部署的结果都可能不一样。今天能跑,明天可能就挂了。为什么?因为有人中间合入了未测试的代码。
3.3.1 版本锁定的做法
我建议用 Git Tag + 版本锁文件 的方式。
- 每次发布前,在 master 上打一个 tag,比如 v1.2.0。
- 在部署脚本里,明确指定拉取某个 tag 的代码。
- 把 tag 信息记录到一个版本锁文件(比如 VERSION_LOCK)中。
示例版本锁文件内容:
# VERSION_LOCK
# 格式:服务名 版本号 部署日期
verify-service v1.2.0 2025-03-15
verify-config v1.0.1 2025-03-14
3.3.2 部署时的拉取流程
我习惯的部署脚本核心逻辑是这样的:
#!/bin/bash
# 部署脚本片段
TAG=$(cat VERSION_LOCK | grep verify-service | awk '{print $2}')
cd /opt/verify-service
git fetch --tags
git checkout tags/$TAG -b deploy-$TAG
# 然后执行构建和启动
为什么要 checkout 到一个新分支?因为这样部署环境里的代码是只读的,不会因为误操作被修改。
3.4 本章知识体系
下面这张图,把代码管理的核心流程串起来了。你可以把它当作一个检查清单。
3.5 避坑指南
最后,分享几个我亲身踩过的坑,希望能帮你省点时间。
- 不要直接在 master 上改代码。哪怕只是改个注释,也走分支流程。我曾经图省事,直接在 master 上改了个配置项,结果忘了 push,别人部署时拉到了旧版本,排查了半天。
- Tag 一旦打了就不要删。删 Tag 会导致历史混乱,尤其是多人协作时。如果打错了,打个新 Tag 覆盖,而不是删除旧的。
- 版本锁文件要纳入版本控制。锁文件本身要入库,这样才能追溯每次部署用的是哪个版本。我见过有人把锁文件放在 .gitignore 里,结果部署环境各自为政,乱成一团。
- 部署脚本里不要用 git pull。用 git fetch + git checkout tag,确保部署的代码是确定的。
代码管理做到位了,后面的部署流程才能稳。说白了,这就是地基活——地基打不牢,上面盖多高都白搭。