两年前编写的文章 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 格式是这样的

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<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 中版本间新增功能,

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

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

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

定位错误

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

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

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

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

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

Commitizen

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

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

$ git czLine 1 will be cropped at 100 characters. All other lines will be wrapped after 100 characters.? Select the type of change that you're committing: (Use arrow keys)
❯ feat:     A new featurefix:      A bug fixdocs:     Documentation only changesstyle:    Changes that do not affect the meaning of the code(white-space, formatting, missing semi-colons, etc)refactor: A code change that neither fixes a bug or adds a featureperf:     A code change that improves performance

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

commit f024d7c0382c4ff8b0543cbd66c6fe05b199bfbc
Author: zhongchiyu <zhongchiyu@gmail.com>
Date:   Mon May 30 14:49:17 2016 +0800fix: 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 包的发布流程,

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

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

Branching Model

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

workflow

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 后,就可以使用它完成分支工作流程,

$ git flow initNo branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]How to name your supporting branch prefixes?
Feature branches? [feature/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []

功能开发

开始开发时

(develop) $ git flow feature start demoSwitched to a new branch 'feature/demo'Summary of actions:
- A new branch 'feature/demo' was created, based on 'develop'
- You are now on branch 'feature/demo'

完成开发后

(feature/demo) $ git flow feature finish demoSwitched to branch 'develop'
Already up-to-date.
Deleted branch feature/demo (was 48fbada).Summary of actions:
- The feature branch 'feature/demo' was merged into 'develop'
- Feature branch 'feature/demo' has been removed
- You are now on branch 'develop'

代码发布

发布代码前

(develop) $ git flow release start demoSwitched to a new branch 'release/demo'Summary of actions:
- A new branch 'release/demo' was created, based on 'develop'
- You are now on branch 'release/demo'

测试完成准备上线时

(release/demo) $ git flow release finish demoSwitched to branch 'master'
Deleted branch release/demo (was 48fbada).Summary of actions:
- Latest objects have been fetched from 'origin'
- Release branch has been merged into 'master'
- The release was tagged 'demo'
- Release branch has been back-merged into 'develop'
- Release branch 'release/demo' has been deleted

发布 master 代码到线上环境

问题修复

发现线上故障时,

(master) $ git flow hotfix start demo-hotfixSwitched to a new branch 'hotfix/demo-hotfix'Summary of actions:
- A new branch 'hotfix/demo-hotfix' was created, based on 'master'
- You are now on branch 'hotfix/demo-hotfix'

修复问题后

(hotfix/demo-hotfix) $ git flow hotfix finish demo-hotfixDeleted branch hotfix/demo-hotfix (was 48fbada).Summary of actions:
- Latest objects have been fetched from 'origin'
- Hotfix branch has been merged into 'master'
- The hotfix was tagged 'demo-hotfix'
- Hotfix branch has been back-merged into 'develop'
- 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

正确的 Git 提交记录和分支模型相关推荐

  1. IDEA--通过cherrypick实现指定几条git提交记录合并到新分支

    [学习背景] Hi,大家好,我是贾斯汀,今天分享一个工作经验小技巧,相信很多小伙伴都有使用IDEA编写代码,然后git作为版本控制,可能大家平时比较习惯用的是从原分支合并(merge)所有提交记录到新 ...

  2. GIT提交记录和Revert commit过程分析

    一.根据GIT提交记录查看提交过程 先做个git分支的背景介绍 图1 步骤说明 1⃣️ 项目A 默认分支是 master 2⃣️ 基于master分支创建 f1.f2.test分支 3⃣️ f1 发起 ...

  3. git合并两个没有共同历史提交记录的分支:fatal: refusing to merge unrelated histories

    场景:某个git仓库原有 master 分支,后面自己本地新建了一个项目,然后把新建的这个推到了这个仓库的另外一个分支 feature/vue-pc .现在要对这两个分支进行合并,该如何操作? 正常情 ...

  4. AndroidStudio git 提交代码,创建分支,合并分支,回滚版本,拉取代码

    主要有: 提交代码,创建分支,合并分支,回滚版本,拉去代码 1 首先电脑中下载git 2 新建的项目把.git 仓库放到项目总中as 工具的右下角 会显示 Git:master 点击有一个弹框如下 然 ...

  5. 清理Git提交记录最简单的方法

    创建分支名列如下: git checkout --orphan tmp 该命令会创建一个名为tmp的分支,并且该分支会包含父分支的所有文件.但新的分支不会指向任何以前的提交,也就是没有提交历史,如果你 ...

  6. git提交代码时分支问题报Your branch is up-to-date with ‘origin/master‘

    Your branch is up to date with 'origin/master' 今天git提交的时候遇到了一些小问题,就是这个亚子啦: 找到一些方法记在小本本上 据说是版本分支的问题,需 ...

  7. 如何维持整洁的 Git 提交记录?送你三个锦囊!

    背景 大家都有学习如何规范简洁的编写代码,但却很少学习如何规范简洁的提交代码.现在大家基本上都用 Git 作为源码管理的工具,Git 提供了极大的灵活性,我们按照各种 workflow 来提交/合并 ...

  8. git commit --amend 修改git提交记录用法详解

    有时你提交过代码之后,发现一个地方改错了,你下次提交时不想保留上一次的记录:或者你上一次的commit message的描述有误,这时候你可以使用接下来的这个命令:git commit --amend ...

  9. git 提交到某分支_Git如何拉取某个分支的某段提交

    大家都说的对,没有什么好办法:但我实际工作过程中还是有这个特殊需求的. 今天晚上我用我蹩脚的shell编程能力写了一段程序可以实现我的需求,还是通过cherry-pick实现. 该小程序,只要如下这么 ...

最新文章

  1. android Service 的使用
  2. Linux环境thinkphp配置以及数据源驱动修改
  3. CoreOS 和 Kubernetes 1.5 自主运行 Kubernetes、Container Linux
  4. datastore_使用Spring Session和JDBC DataStore进行会话管理
  5. python 事务操作_Python实现连接mysql数据库及事务处理【冰斌棒】
  6. 【js】正则表达式(II)
  7. Oracle事务隔离级别
  8. java spring 事务提交_Spring 事务提交之后再执行操作
  9. linux命令iconv_Linux中iconv命令的简介和使用方法
  10. 读书笔记 - Thoughts on interaction design (第二版) - 交互设计沉思录
  11. 企业进销存管理系统(一)
  12. 紧急求助SPSS大神。spss在xml神经网络预测值为空是怎么回事?
  13. 彻底弄懂 Nginx location 匹配
  14. 信号完整性基础01:从频域出发理解信号(1)-时域和频域
  15. 农历和阳历互转(c语言)
  16. 南京市城镇居民基本医疗保险暂行办法实施细则
  17. 计算机科学中atm是什么,计算机专业知识:ATM网络基本原理
  18. OSChina 周四乱弹 ——一周五天在诈尸
  19. 含源码 | C语言做可写入文件的账号密码登录系统
  20. 下载并安装MS office 365

热门文章

  1. nginx禁止对写操作timeout时retry
  2. curl获取结果乱码的解决方法之CURLOPT_ENCODING(curl/Post请求)
  3. Web网页布局的主要方式
  4. zabbix应用之短信报警
  5. 【iOS-cocos2d-X 游戏开发之十一】使用New CCSprite() CCUserDefault要注意!
  6. Matlab绘图基础——利用axes(坐标系图形对象)绘制重叠图像 及 一图多轴(一幅图绘制多个坐标轴)
  7. 使用FFmpeg命令行进行UDP、RTP推流(H264、TS),ffplay接收
  8. 在C/C++语言中使用正则表达式
  9. 2-结构体的最后一个成员的定义-C语言中的柔性数组-
  10. javascript之模拟call以及apply实现