原文地址:https://mp.weixin.qq.com/s/TziYXZ0hGBre4QiPLL8KCw

  • Commit Message
    • 格式
    • 应用
    • Commitizen
  • Branching Model
    • gitflow
    • 相关链接

两年前编写的文章 Git Style,是参考业界实践对 Git 提交记录格式和分支模型所做的总结。本文在 Git Style 基础上,再次描述提交记录的格式和分支模型,并介绍两个工具 commitizen 和 gitflow,分别处理维护提交记录格式和分支切换的工作

Commit Message

在 Git Style 中已经介绍了提交记录(Commit Message)的格式,但是没有说明为什么要遵循这样的约定。事实上,这个格式参考了 AngularJS’s commit message convention,而 AngularJS 制定这样的约定是出于几个目的

  • 自动生成 CHANGELOG.md
  • 识别不重要的提交
  • 为浏览提交历史时提供更好的信息

后面简称 AngularJS’s commit message convention 为 conventional message。

格式

Conventional message 格式是这样的

  1. <type>(<scope>): <subject>
  2. <BLANK LINE>
  3. <body>
  4. <BLANK LINE>
  5. <footer>

subject 是对变更的简要描述。

body 是更为详细的描述。

type 则定义了此次变更的类型,只能使用下面几种类型

  • feat:增加新功能
  • fix:问题修复
  • docs:文档变更
  • style:代码风格变更(不影响功能)
  • refactor:既不是新功能也不是问题修复的代码变更
  • perf:改善性能
  • test:增加测试
  • chore:开发工具(构建,脚手架工具等)

footer 可以包含 Breaking Changes 和 Closes 信息。

应用

node-trail-agent 项目遵循 conventional message,这里以这个项目举例,演示其应用场景。

CHANGELOG

通过 git log 可以生成 CHANGELOG.md 中版本间新增功能,

  1. $ git log v0.4.0..v1.1.2 --grep feat --pretty=format:%s
  2. feat: add "type" tag to distinguish client and server span
  3. feat: instrument via Module._load hook

也可以同时获取修复的问题,

  1. $ git log v0.4.0..v1.1.2 --grep 'feat\|fix' --pretty=format:%s
  2. fix: wrapper function not returned
  3. feat: add "type" tag to distinguish client and server span
  4. feat: instrument via Module._load hook

定位错误

使用 git bisect 可以定位引入问题的提交,通过 type 可以快速辨别不会引入 bug 的提交,

  1. (master) $ git bisect start
  2. (master) $ git bisect bad
  3. (master) $ gco v0.1.0
  4. (7f04616) $ git bisect good
  5. Bisecting: 15 revisions left to test after this (roughly 4 steps)
  6. [433f58f26a53b519ab7fc52927895e67eb068c64] docs: how to use agent
  7. (433f58f) $ git bisect good
  8. Bisecting: 7 revisions left to test after this (roughly 3 steps)
  9. [02894fb497f41eecc7b21462d3b020687b3aaee2] docs(CHANGELOG): 1.1.0
  10. (02894fb) $ git bisect good
  11. Bisecting: 3 revisions left to test after this (roughly 2 steps)
  12. [9d15ca2166075aa180cd38a3b4d3be22aa336575] chore(release): 1.1.1
  13. (9d15ca2) $ git bisect good
  14. Bisecting: 1 revision left to test after this (roughly 1 step)
  15. [f024d7c0382c4ff8b0543cbd66c6fe05b199bfbc] fix: wrapper function not returned
  16. (f024d7c) $ npm test
  17. ...

因为 docs 或 chore 不会引入 bug,所以可以直接执行 git bisect good

使用 git bisect skip 可以直接过滤掉这些提交,

  1. $ git bisect skip $(git rev-list --grep 'style\|docs\|chore' v0.1.0..HEAD)

Commitizen

命令行工具 commitizen 帮助开发者生成符合 conventional message 的提交记录。

成功安装并初始化 commitizen 后,通过调用 git cz 来提交代码,

  1. $ git cz
  2. Line 1 will be cropped at 100 characters. All other lines will be wrapped after 100 characters.
  3. ? Select the type of change that you're committing: (Use arrow keys)
  4. ❯ feat: A new feature
  5. fix: A bug fix
  6. docs: Documentation only changes
  7. style: Changes that do not affect the meaning of the code
  8. (white-space, formatting, missing semi-colons, etc)
  9. refactor: A code change that neither fixes a bug or adds a feature
  10. perf: A code change that improves performance

提交后会按照 convertional message 格式化提交记录,

  1. commit f024d7c0382c4ff8b0543cbd66c6fe05b199bfbc
  2. Author: zhongchiyu <zhongchiyu@gmail.com>
  3. Date: Mon May 30 14:49:17 2016 +0800
  4. fix: wrapper function not returned

除此之外,commitizen 还依据 conventional message,创建起一个生态

  • conventional-changelog-cli:通过提交记录生成 CHANGELOG.md
  • conventional-github-releaser:通过提交记录生成 github release 中的变更描述
  • conventional-recommended-bump:根据提交记录判断需要升级 Semantic Versioning 哪一位版本号
  • validate-commit-msg:检查提交记录是否符合约定

使用这些工具可以简化 npm 包的发布流程,

  1. #! /bin/bash
  2. # https://gist.github.com/stevemao/280ef22ee861323993a0
  3. # npm install -g commitizen cz-conventional-changelog trash-cli conventional-recommended-bump conventional-changelog-cli conventional-commits-detector json
  4. trash node_modules &>/dev/null;
  5. git pull --rebase &&
  6. npm install &&
  7. npm test &&
  8. cp package.json _package.json &&
  9. preset=`conventional-commits-detector` &&
  10. echo $preset &&
  11. bump=`conventional-recommended-bump -p angular` &&
  12. echo ${1:-$bump} &&
  13. npm --no-git-tag-version version ${1:-$bump} &>/dev/null &&
  14. conventional-changelog -i History.md -s -p ${2:-$preset} &&
  15. git add History.md &&
  16. version=`cat package.json | json version` &&
  17. git commit -m"docs(CHANGELOG): $version" &&
  18. mv -f _package.json package.json &&
  19. npm version ${1:-$bump} -m "chore(release): %s" &&
  20. git push --follow-tags &&
  21. npm publish

运行上述脚本会更新 CHANGELOG.md、升级版本号并发布新版本到 npm,所有这些操作都基于提交记录自动处理。

Branching Model

Vincent Driessen 的分支模型(Branching Model)介绍 Git 分支和开发,部署,问题修复时的工作流程,
提交记录和分支模型 - 图1

Author: Vincent Driessen Original blog post: http://nvie.com/posts/a-succesful-git-branching-model License: Creative Commons BY-SA

在整个开发流程中,始终存在 master 和 develop 分支,其中 master 分支代码和生产环境代码保持一致,develop 分支还包括新功能代码。

分支模型主要涉及三个过程:功能开发,代码发布和问题修复

功能开发

  1. 从 develop 创建一个新分支(feature/*)
  2. 功能开发
  3. 生产环境测试
  4. Review
  5. Merge 回 develop 分支

代码发布

需要发布新功能到生产环境时

  1. 从 develop 创建新分支(release/*)
  2. 发布 feature 分支代码到预上线环境
  3. 测试并修复问题
  4. Review
  5. 分别 merge 回 develop 和 master 分支
  6. 发布 master 代码到生产环境

问题修复

当生产环境代码出现问题需要立刻修复时

  1. 从 master 创建新分支(hotfix/*)
  2. 发布 hotfix 代码到预上线环境
  3. 修复问题并测试
  4. Review
  5. 分别 merge 会 develop 和 master 分支
  6. 发布 master 代码到生产环境

该分支模型值得借鉴的地方包括,

  • 规范的分支命名
  • 将分支和代码运行环境关联起来

分支和代码运行环境的关系是这样的,

  • master => 生产环境
  • release/,hotfix/ => 预上线环境
  • feature/*,develop => 开发环境

gitflow

Vincent Driessen 的分支模型将开发流程和Git分支很好的结合起来,但在实际使用中涉及复杂的分支切换,gitflow 可以简化这些工作。

安装并在代码仓库初始化 gitflow 后,就可以使用它完成分支工作流程,

  1. $ git flow init
  2. No branches exist yet. Base branches must be created now.
  3. Branch name for production releases: [master]
  4. Branch name for "next release" development: [develop]
  5. How to name your supporting branch prefixes?
  6. Feature branches? [feature/]
  7. Release branches? [release/]
  8. Hotfix branches? [hotfix/]
  9. Support branches? [support/]
  10. Version tag prefix? []

功能开发

开始开发时

  1. (develop) $ git flow feature start demo
  2. Switched to a new branch 'feature/demo'
  3. Summary of actions:
  4. - A new branch 'feature/demo' was created, based on 'develop'
  5. - You are now on branch 'feature/demo'

完成开发后

  1. (feature/demo) $ git flow feature finish demo
  2. Switched to branch 'develop'
  3. Already up-to-date.
  4. Deleted branch feature/demo (was 48fbada).
  5. Summary of actions:
  6. - The feature branch 'feature/demo' was merged into 'develop'
  7. - Feature branch 'feature/demo' has been removed
  8. - You are now on branch 'develop'

代码发布

发布代码前

  1. (develop) $ git flow release start demo
  2. Switched to a new branch 'release/demo'
  3. Summary of actions:
  4. - A new branch 'release/demo' was created, based on 'develop'
  5. - You are now on branch 'release/demo'

测试完成准备上线时

  1. (release/demo) $ git flow release finish demo
  2. Switched to branch 'master'
  3. Deleted branch release/demo (was 48fbada).
  4. Summary of actions:
  5. - Latest objects have been fetched from 'origin'
  6. - Release branch has been merged into 'master'
  7. - The release was tagged 'demo'
  8. - Release branch has been back-merged into 'develop'
  9. - Release branch 'release/demo' has been deleted

发布 master 代码到线上环境

问题修复

发现线上故障时,

  1. (master) $ git flow hotfix start demo-hotfix
  2. Switched to a new branch 'hotfix/demo-hotfix'
  3. Summary of actions:
  4. - A new branch 'hotfix/demo-hotfix' was created, based on 'master'
  5. - You are now on branch 'hotfix/demo-hotfix'

修复问题后

  1. (hotfix/demo-hotfix) $ git flow hotfix finish demo-hotfix
  2. Deleted branch hotfix/demo-hotfix (was 48fbada).
  3. Summary of actions:
  4. - Latest objects have been fetched from 'origin'
  5. - Hotfix branch has been merged into 'master'
  6. - The hotfix was tagged 'demo-hotfix'
  7. - Hotfix branch has been back-merged into 'develop'
  8. - Hotfix branch 'hotfix/demo-hotfix' has been deleted

相关链接

  • commitizen
  • gitflow
  • AngularJS Git Commit Message Conventions
  • Git Style
  • node-trail-agent
  • A successful Git branching model
  • Using git-flow to automate your git branching workflow