代码提交+分支管理+版本管理最佳实践

目录
以更契合工程师习惯的 YAML 文档格式,展示约定式提交、分支管理模型、语义化版本与基于源代码的版本等最佳实践。
约定式提交
规范
网站:
- https://www.conventionalcommits.org
- https://github.com/commitizen/conventional-commit-types/blob/master/index.json
conventional_commits:
feat: new feature
fix: bug fix
docs: documentation only changes
style: changes that do not affect the meaning of the code, e.g., white-space, formatting, missing semi-colons
refactor: code change that neither fixes a bug nor adds a feature
perf: code change that improves performance
test: adding missing tests or correcting existing tests
build: changes that affect the build system or external dependencies, e.g., gulp, broccoli, npm
ci: changes to our CI configuration files and scripts, e.g., Travis, Circle, BrowserStack, SauceLabs
chore: other changes that do not modify src or test files
revert: reverts a previous commit
约定式提交:
feat: 新功能(feature)
fix: 修复bug
docs: 文档(documents)
style: 格式, 不影响代码运行
refactor: 重构
perf: 优化(performance), 提升性能或体验
test: 测试
build: 构建或依赖项更新
ci: 持续集成(continuous integration)
chore: 其它杂务
revert: 撤销之前的提交
structure: <type>(scope): <subject>
动词别名:
fix:
- resolve
- handle
- correct
- prevent
- update
示例
-
With description and breaking change footer
feat: allow provided config object to extend other configs BREAKING CHANGE: `extends` key in config file is now used for extending other config files
-
With
!
to draw attention to breaking changefeat!: send an email to the customer when a product is shipped
-
With scope and
!
to draw attention to breaking changefeat(api)!: send an email to the customer when a product is shipped
-
With both
!
and BREAKING CHANGE footerchore!: drop support for Node 6 BREAKING CHANGE: use JavaScript features not available in Node 6.
-
With no body
docs: correct spelling of CHANGELOG
-
With scope
feat(lang): add Polish language
-
With multi-paragraph body and multiple footers
fix: prevent racing of requests Introduce a request id and a reference to latest request. Dismiss incoming responses other than from latest request. Remove timeouts which were used to mitigate the racing issue but are obsolete now. Reviewed-by: Z Refs: #123
-
With a footer that references the commit SHA that is being reverted
revert: feat(lang): add Polish language This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
分支管理模型
Gitflow
Gitflow:
网站:
- https://nvie.com/posts/a-successful-git-branching-model/
- https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow
描述: 传统工作流, 适合有明确发布周期和多人协作的项目
分支:
feature/*: 功能开发分支, 例如 feature/login, feature/JIRA-985-login
bugfix/*: 修复已知的非紧急缺陷, 例如 bugfix/sso-auth, bugfix/JIRA-211-sso-auth
develop: 开发集成分支, 合并多个 feature 和 bugfix
release/*: 候选发布分支, 例如 release/1.6.2
hotfix/*: 生产环境热修复, 例如 hotfix/1.6.3
main: 生产环境稳定分支
流程:
# 开发流程: feature/bugfix 从 develop 拉取, 完成后合并回 develop, 再通过 release 合并到 main, 并在 main 上打 tag 标记版本
develop → feature/bugfix → develop → release → main → tag(vX.Y.Z)[推荐]
# 紧急修复: hotfix 从 main 拉取, 完成后合并回 develop 和 main, 并在 main 上打 tag 标记版本
main → hotfix
↘ develop
↘ main → tag(vX.Y.Z)[推荐]
优点:
- 明确的分支角色, 适合版本化管理
- 方便管理发布和修复流程
缺点:
- 分支较多, CI/CD 流程复杂
- 不适合高频率持续交付
扩展(可选):
分支:
user/<name>/*: 个人分支, 例如 user/john/login, user/alice/sso-auth
env/*: 环境分支, 例如 env/uat, env/prod
说明:
- user/<name>/* 仅用于个人实验或独立开发, 不保证会合并, 避免污染正式功能分支
- env/* 仅用于跟踪各环境当前部署版本, 不直接开发代码, 更新通过合并提交
GitHub Flow
GitHubFlow:
网站: https://docs.github.com/en/get-started/using-github/github-flow
描述: 简化流程, 适合持续交付和小团队
分支:
main: 唯一的长期分支, 始终保持可发布状态, 是否发布由团队策略决定
feature/*: 从 main 派生的功能分支
流程:
# 功能开发: feature 从 main 拉取, 完成后通过 Pull/Merge Request 合并回 main
# 发布版本: 在 main 上打 tag 标记可发布版本
main → feature → main → tag(vX.Y.Z)[推荐]
优点:
- 流程简单, 适合快速迭代
- 结合 Pull/Merge Request 审核
缺点:
- 缺少稳定的开发集成分支
- 版本控制需要依赖 tag
Trunk Based Development
TrunkBasedDevelopment:
网站: https://cn.trunkbaseddevelopment.com
描述: 主干开发, 极简工作流, 适合持续集成/每日构建
分支:
main: 唯一的主干分支 (Trunk)
feature/*: 非常短期的功能分支, 快速合并回 main
流程:
# 功能开发: feature 从 main 拉取, 短周期开发后快速合并回 main
# 持续发布: 每次 main 合并都可触发构建和发布
main → feature → main → tag(vX.Y.Z)[可选]
说明:
- 由于合并频繁, 通常使用 `datetime + commit_hash` 作为版本号, 例如 2025.07.30.19.06.3f9a7c1d
- 语义化版本 (vX.Y.Z) 仅用于重要的里程碑 tag
优点:
- 支持高频率发布, 自动化 CI/CD 友好
- 避免长期分支造成代码漂移(长期未合并导致代码差异累积)
缺点:
- 需要强大的测试和自动化保障
- 对团队协作要求高
GitLab Flow
GitLabFlow:
网站: https://about.gitlab.com/blog/gitlab-flow-duo/
描述: GitLab 官方推荐的工作流, 结合主干开发与环境分支, 适合多环境 CI/CD 部署
分支:
feature/*: 功能开发分支, 从 main 派生, 完成后通过 Merge Request 合并回 main
main: 主分支, 用于集成和测试, 始终保持可合并状态
staging: 预发布环境分支, 用于上线前验证
production: 生产环境分支, 跟踪当前线上部署版本
流程:
# 功能开发: feature 从 main 拉取, 完成后合并回 main
# 部署流程: main 合并到 staging 触发预发布, main 合并到 production 触发生产部署
# 可选发布: 在 production 上打 tag 标记生产版本
main → feature → main
↘ staging
↘ production → tag(vX.Y.Z)[推荐]
说明:
- staging/production 分支用于跟踪各环境当前部署版本
- 更新环境分支通过合并提交完成, 不直接在这些分支上开发代码
- main 合并到 production 时推荐打 tag 标记正式发布版本
优点:
- 支持多环境部署, CI/CD 友好
- 通过环境分支管理发布, 直观跟踪当前部署状态
- 保持 main 分支简洁, 功能通过 Merge Request 控制
缺点:
- 需要严格的合并策略和 CI/CD 约定
- 对小型项目可能过于复杂
版本管理
标签命名
version_label:
snapshot: 开发快照
alpha: 内部测试
beta: 公开测试
rc: 候选发布 # Release Candidate
release: 正式发布
hotfix: 紧急修复
语义化版本
语义化版本:
英文: Semantic Versioning
网站: https://semver.org
格式: MAJOR.MINOR.PATCH
初始化开发版本: 0.1.0
说明:
MAJOR:
描述: 主版本号
场景: 不兼容的修改
示例: 0.12.8 → 1.0.0
规则: 主版本号 +1, 次版本号和修订号归零
MINOR:
描述: 次版本号
场景: 向下兼容的功能性新增
示例: 1.5.1 → 1.6.0
规则: 次版本号 +1, 修订号归零
PATCH:
描述: 修订号
场景: 向下兼容的问题修正
示例: 1.6.1 → 1.6.2
规则: 修订号 +1
预发布版本:
格式: MAJOR.MINOR.PATCH-<label>[.<identifier>]
标签:
alpha: 内部测试版
beta: 公开测试版
rc: 候选发布版 # Release Candidate
示例:
- 1.12.6-alpha
- 1.12.6-beta
- 1.12.6-rc.1
- 1.12.6-rc.2
元数据:
格式: MAJOR.MINOR.PATCH[-<label>]+<metadata>
示例:
- 1.12.6-alpha+3f9a7c1d
- 1.12.7+20250730
版本演进路线示例: |
0.1.0 → 0.1.1 → ...
↓
...
↓
0.12.8
↓
1.0.0
↓
...
↓
1.5.1
↓
1.6.0 → 1.6.1 → 1.6.2
↓
...
↓
1.12.6-alpha(1.12.6-alpha+3f9a7c1d) → 1.12.6-beta → 1.12.6-rc.1 → 1.12.6-rc.2
↓
1.12.7(1.12.7+20250730)
基于源代码的版本
基于源代码的版本:
英文: Source-based Versioning
格式: <branch>-YYYYMMDDHHmm-<commit_hash>
说明:
branch: 分支
YYYYMMDDHHmm: 构建日期时间
commit_hash: 短哈希值(前8位字符)
示例:
- feature-login-202507281802-c4d8b21e
- develop-202507291752-b17e5a9f
- main-202507301906-3f9a7c1d
优点:
- 直接显示构建来源分支
- 每个版本唯一且可追溯到具体提交
- 适合自动化持续集成
扩展规则:
带发布标签:
格式: <branch>-YYYYMMDDHHmm-<commit_hash>-<label>
标签:
alpha: 内部测试版
beta: 公开测试版
rc: 候选发布版 # Release Candidate
示例:
- main-202507301906-3f9a7c1d-alpha
GitLab CI 版本号生成
# .gitlab-ci.magic-version.yml
variables:
TAG_PREFIX: "v" # 定义 tag 前缀, 用于去掉类似 v1.2.3 的 v
# 基于 tag 的版本
version_tag:
stage: magic_version
rules:
- if: $CI_COMMIT_TAG =~ /^.+/ # 仅在有 tag 的情况下运行, /^.+/ 即只要有一个非空字符就返回 true
script:
# 取当前 tag, 去掉 TAG_PREFIX 前缀, 例如 v1.2.3 -> 1.2.3
- export MAGIC_VERSION=${CI_COMMIT_TAG#*"$TAG_PREFIX"}
# 把版本号写入 build.env, 供后续 Job 使用
- echo "MAGIC_VERSION=$MAGIC_VERSION" >> build.env
artifacts:
reports:
dotenv: build.env # 把 build.env 导出为 dotenv, 供后续 Job 使用 $MAGIC_VERSION 变量
# 基于 分支 的版本
version_branch:
stage: magic_version
rules:
- if: $CI_COMMIT_BRANCH # 当基于 分支 构建时运行
script:
# 生成日期时间, 格式为 YYYYMMDDHHmm, 例如 202507301906
- VERSION_DATETIME=$(date +'%Y%m%d%H%M')
# 拼接版本号:<branch>-YYYYMMDDHHmm-<commit_hash>
# 例如:main-202507301906-3f9a7c1d
# 变量说明:
# $CI_COMMIT_REF_SLUG -> 分支名 slug, 例如 feature-login / main
# $CI_COMMIT_SHORT_SHA -> 当前提交的短哈希值(前8位字符)
- export MAGIC_VERSION=${CI_COMMIT_REF_SLUG}-${VERSION_DATETIME}-${CI_COMMIT_SHORT_SHA}
# 把版本号写入 build.env, 供后续 Job 使用
- echo "MAGIC_VERSION=$MAGIC_VERSION" >> build.env
artifacts:
reports:
dotenv: build.env # 把 build.env 导出为 dotenv, 供后续 Job 使用 $MAGIC_VERSION 变量