jjzjj

git commit规范

前端小奈 2024-07-16 原文

如何规范git commit提交

github是我们用于协同开发的平台,方便开发人员协同开发,极大提高了开发效率,但是经过团队第一次协同开发后,我们发现了一个很大的问题,我们的git commit非常不规范,至于在开发后期项目出现bug之后,很难找到问题所在,为了规范以后的开发,学习使用commitizen,husky以及standard-version来规返回git commit提交,并且自动化生成CHANGLOG

commitizen

commitizen是用来制定git commit规范的工具

首先让我们了解一下commitizen制定的git commit规范格式

要想规范git commit提交,我们要先了解一下Commit Message格式,目前使用较多的是Angular团队规范,继而衍生出Conventional Commits specification很多工具也是基于此规范,它的message格式如下:

每次提交,Commit Message都包括如下三个部分:Header, Body和Footer

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

其中,Header 是必需的,Body 和 Footer 可以省略。

不管是哪一个部分,任何一行都不得超过100个字符。这是为了避免自动换行影响美观。

  • 标题行(第一行/header): 必填, 描述主要修改类型和内容
  • 主题内容(body): 描述为什么修改, 做了什么样的修改, 以及开发的思路等等
  • 页脚注释(footer): 放 Breaking Changes 或 Closed Issues
  • scope: commit 影响的范围, 比如: route, component, utils, build…
  • subject: commit 的概述, 建议符合 50/72 formatting
  • body: commit 具体修改内容, 可以分为多行, 建议符合 50/72 formatting
  • footer: 一些备注, 通常是 BREAKING CHANGE 或修复的 bug 的链接.

注:该工具要输入时都可以用\n 来换行操作, 回车直接结束描述!!如果想结束重来可以使用ctrl + c

Header部分只有一行,包括三个字段:type(必需)、scope(可选)和subject(必需)。

type(必填)

type用于说明 commit 的类别。

  • feat:新增功能
  • fix:bug 修复
  • docs:文档更新
  • style:不影响程序逻辑的代码修改(修改空白字符,格式缩进,补全缺失的分号等,没有改变代码逻辑)
  • refactor:重构代码(既没有新增功能,也没有修复 bug)
  • perf:性能, 体验优化
  • test:新增测试用例或是更新现有测试
  • build:主要目的是修改项目构建系统(例如 glup,webpack,rollup 的配置等)的提交
  • ci:主要目的是修改项目继续集成流程(例如 Travis,Jenkins,GitLab CI,Circle等)的提交
  • chore:不属于以上类型的其他类,比如构建流程, 依赖管理
  • revert:回滚某个更早之前的提交

如果typefeatfix,则该 commit 将肯定出现在 Change log 之中。其他情况(docschorestylerefactortest)由你决定,要不要放入 Change log,建议是不要。

scope(可选)

scope用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,视项目不同而不同。

subject(必填):

subject是 commit 目的的简短描述,

  • 以动词开头,使用第一人称现在时,比如change,而不是changedchanges
  • 第一个字母小写
  • 结尾不加句号(.

Body(可省)

Body 部分是对本次 commit 的详细描述,可以分成多行。

有两个注意点。

(1)使用第一人称现在时,比如使用change而不是changedchanges

(2)应该说明代码变动的动机,以及与以前行为的对比。

Footer(可省)

Footer 部分只用于两种情况。

1)不兼容变动

如果当前代码与上一个版本不兼容,则 Footer 部分以BREAKING CHANGE开头,后面是对变动的描述、以及变动理由和迁移方法。

2)关闭 Issue

如果当前 commit 针对某个issue,那么可以在 Footer 部分关闭这个 issue 。

Closes #234

也可以一次关闭多个 issue 。

Closes #123, #245, #992

Revert

还有一种特殊情况,如果当前 commit 用于撤销以前的 commit,则必须以 revert: 开头,后面跟着被撤销 Commit 的 Header。

revert: feat(pencil): add 'graphiteWidth' option

This reverts commit 667ecc1654a317a13331b17617d973392f415f02.

Body部分的格式是固定的,必须写成 This reverts commit <hash>. ,其中的 hash 是被撤销 commit 的 SHA 标识符。

如果当前 commit 与被撤销的 commit,在同一个发布(release)里面,那么它们都不会出现在 Change log 里面。如果两者在不同的发布,那么当前 commit,会出现在 Change log 的 Reverts 小标题下面。

用Commitizen替代你的 git commit (使用工具生成符合规范的commit message)

上面我们已经了解了Commit Message的格式是什么样的了,如果让我们自己手动敲出那些格式也不是不可能,但是我相信那不是程序员的作风,大多数人会疯掉吧,,那么就需要通过commitizen/cz-cli 工具, 帮助我们生成符合规范的 commit message .

安装命令如下。

npm install --save-dev commitizen

安装commitlint cli 和传统配置

npm install --save-dev @commitlint/config-conventional @commitlint/cli

在根目录下新建commitlint.config.js制定提交message规范

/**
 * feat:新增功能
 * fix:bug 修复
 * docs:文档更新
 * style:不影响程序逻辑的代码修改(修改空白字符,格式缩进,补全缺失的分号等,没有改变代码逻辑)
 * refactor:重构代码(既没有新增功能,也没有修复 bug)
 * perf:性能, 体验优化
 * test:新增测试用例或是更新现有测试
 * build:主要目的是修改项目构建系统(例如 glup,webpack,rollup 的配置等)的提交
 * ci:主要目的是修改项目继续集成流程(例如 Travis,Jenkins,GitLab CI,Circle等)的提交
 * chore:不属于以上类型的其他类型,比如构建流程, 依赖管理
 * revert:回滚某个更早之前的提交
*/



module.exports = { extends: ['@commitlint/config-conventional'] };

因为commitizen工具是基于Node.js的,对于没有package.json文件的项目上面命令会不成功,所以先创建一个空的package.json文件,再执行上面命令即可,有package.json文件的项目可以忽略本条命令。

npm init --yes

husky

配置好commitizen之后,我们就可以使用husky来进行commit message规范检测了

什么是husky?(GitHoook工具-husky介绍及使用)

husky继承了Git下所有的钩子,在触发钩子的时候,husky可以阻止不合法的commit, push等操作(注意:在使用husky之前,必须先将代码放到git仓库中,否则没有本地.git文件,就没有地方去继承钩子了)

接下来先安装husky

npm install husky@4.3.8 --save-dev 
或者
yarn add husky@4.3.8 -D

这里需要注意一点是安装最新husky版本会出现各种问题,在使用git commit时不生效或者出现如下情况

$ git commit -m "xx"

error Command "husky-run" not found.

查看pageage.json发现安装的husky的版本"husky" : "^7.0.1"但是第三方开源库使用的是4.3.8,所以建议大家使用4.3.8版本

然后在package.json文件通过字段直接添加git钩子

// package.json
{
  "husky": {
    "hooks": {
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS,"  //commitlint检测
      "pre-commit": "npm run stylelintt && npm run eslintt"  //js、css检测,这两个检测需要自己配置,pre-commit会优先于commit-msg执行
    }  
  }
}


配置完成之后我们可以使用如下方式提交Git commit

使用命令 git commit -m "feat : 添加功能"

我们可以看到执行命令之后,husky就帮我们进行了commit message检测

或者使用git commit这样将会打开一个COMMIUT_EDITMSG文件,在此文件内进行填写commit message内容,写完后,关闭此文件,husky将自动检测内容是否符合规范

standard-version

在安装standard-version之前要先安装commitizen,我们需要遵循 Conventional Commit Specifications 来进行标准化的 commit message 编写,这是因为 standard-version 是基于 commit 类型来更新版本号的(feature 会更新 minor, bug fix 会更新 patch, BREAKING CHANGES 会更新 major)。commitizen 可以帮助我们提交符合 Conventional Commit Specifications 的 commit message。

当我们使用 commitizen 进行标准化提交之后,我们就可以使用 standard-version 进行版本管理自动化了,包括更新 CHANGELOG.md,以及使用 git tag

  1. 安装 standard-version
npm install -D standard-version
  1. package.json 中编写响应的脚本:
"scripts": {
  "release": "standard-version"
}

如果是第一次运行来生成CHANGELOG则使用命令npx standard-version --first-release,会基于package.json的version来生成CHANGELOG。并不会对版本号进行修改,在以后需要发布版本时直接运行npm run release即可

CHANGELOG.md 配置

默认情况下,standard-version 只会在 CHANGELOG.md 中记录 feat:新增功能fix:修复bug 类型的提交(所以盲猜CHANGELOG应该是为了观察项目版本变化的)。如果想记录其他类型的提交,需要如下步骤:

  • 在项目的根目录下创建一个名为 .versionrc 的文件,并粘贴复制一下内容:
// .versionrc
{
  "types": [
    {"type": "chore", "section":"Others", "hidden": false},
    {"type": "revert", "section":"Reverts", "hidden": false},
    {"type": "feat", "section": "Features", "hidden": false},
    {"type": "fix", "section": "Bug Fixes", "hidden": false},
    {"type": "improvement", "section": "Feature Improvements", "hidden": false},
    {"type": "docs", "section":"Docs", "hidden": false},
    {"type": "style", "section":"Styling", "hidden": false},
    {"type": "refactor", "section":"Code Refactoring", "hidden": false},
    {"type": "perf", "section":"Performance Improvements", "hidden": false},
    {"type": "test", "section":"Tests", "hidden": false},
    {"type": "build", "section":"Build System", "hidden": false},
    {"type": "ci", "section":"CI", "hidden":false}
  ]
}
  • "type" commit 类型
  • "section" 不同的 commit 类型所在 CHANGELOG.md 中的区域
  • "hidden" 是否在 CHANGELOG.md 中显示

可视化

安装git graph可将我们的git commit提交的具体内容进行可视化

git graph可以灵活的选择分支,查看日期,作者。

安装:

在VScode应用商店下载git graph

然后点击源代码管理

发现多了一个view git graph

然后试试提交命令,git graph将同步更新你的提交内容

有关git commit规范的更多相关文章

  1. ruby - gem 规范失败 - 2

    我正在为毕业设计开发GEM,TravisCI构建不断失败。这是我在Travis上的链接:https://travis-ci.org/ricardobond/perpetuus/builds/8709218构建错误是:$bundleexecrakerakeaborted!Don'tknowhowtobuildtask'default'/home/travis/.rvm/gems/ruby-1.9.3-p448/bin/ruby_noexec_wrapper:14:in`eval'/home/travis/.rvm/gems/ruby-1.9.3-p448/bin/ruby_noexec_

  2. ruby - 如何禁止在 RSpec 中显示挂起(跳过)的规范? - 2

    我有几个跳过的规范。Pending:(Failureslistedhereareexpectedanddonotaffectyoursuite'sstatus)1)...#Notyetimplemented#./spec/requests/request_spec.rb:22如何抑制未决规范的输出? 最佳答案 您可以添加以下配置选项以从运行中过滤掉所有待处理的规范:RSpec.configuredo|config|config.filter_run_excludingskip:trueend此外,here是一个更详细的抑制输出的建议

  3. ruby-on-rails - 从帮助器规范中 stub 一个帮助器方法 - 2

    我正在构建Rails应用程序并使用RSpec制定测试。我为我正在创建的名为current_link_to的方法编写了测试。此方法应该检查当前页面是否对应于我传递给它的路径,并将current类添加到生成的链接中,以防它匹配。这是规范:require"spec_helper"describeApplicationHelperdodescribe"#current_link_to"dolet(:name){"Products"}let(:path){products_path}let(:rendered){current_link_to(name,path)}context"whenthe

  4. ruby-on-rails - 在 RSpec 中编写请求规范的正确方法是什么? - 2

    tl;dr:跳到最后一段最近一直在尝试使用RSpec的requestspecs做一些更有针对性的测试。我的测试主要是这样的:通用cucumber功能规范,即用户转到带有评论的帖子,对评论点赞,作者获得积分modelspecs当模型实际上具有某些功能时,即User#upvote(comment)controllerspecs我在其中stub了大部分内容,只是试图确保代码按照我期望的方式运行viewspecs当View中有一些复杂的东西时,例如仅在用户尚未投票时呈现upvote链接,这些被stub为好吧问题是当我有一些导致错误的特定场景时,一切似乎都在我无法重现它的模型/View层中工作。

  5. ruby-on-rails - 加速 RSpec 请求规范的方法 - 2

    我有33个规范以大约5秒的速度运行,以这种速度运行会导致测试套件变慢。我追踪到请求规范(4秒以上),因为模型规范只用了一小部分时间。我已经检查过,我的请求规范没有任何过于复杂或不必要的东西,所以我不知道该去哪里让它们更快,而不是只在推送代码之前运行它们以确保一切正常.加快请求规范的最佳方法是什么? 最佳答案 我使用Spork来加速我的测试。它保持整个环境加载以赢得时间。看看这个博客:http://ykyuen.wordpress.com/2010/12/14/rails-running-rspec-with-spork-test-s

  6. ruby-on-rails - Rspec 的 instance_double 创建间歇性规范失败 - 2

    我在使用instance_double时遇到间歇性测试失败。我有一个包含4个规范的文件。这是来源:require'rails_helper'describeSubmitPostdobefore(:each)do@post=instance_double('Post')allow(@post).toreceive(:submitted_at=)endcontext'onsuccess'dobefore(:each)doallow(@post).toreceive(:save).and_return(true)@result=SubmitPost.call(post:@post)endit

  7. ruby - 规范测试基于 EventMachine 的(Reactor)代码 - 2

    我正在尝试整个BDD方法并想测试AMQP基于Vanilla的方面Ruby我正在写的应用程序。选择Minitest后作为与其他名副其实的蔬菜框架不同的平衡功能和表现力的测试框架,我着手编写此规范:#File./test/specs/services/my_service_spec.rb#Requirementsfortestrunningandconfigurationrequire"minitest/autorun"require"./test/specs/spec_helper"#Externalrequires#MinitestSpecsforEventMachinerequire

  8. ruby-on-rails - 在 Rails/Capybara/Poltergeist 规范中使用 url_for 将驱动程序发送到 example.com 而不是应用程序 - 2

    如果我在功能规范中调用url_for,它会返回一个以http://www.example.com/开头的绝对URL.Capybara会很乐意尝试加载该站点上的页面,但这与我的应用程序无关。以下是重现该问题的最少步骤:从这个Gemfile开始:source'https://rubygems.org'gem"sqlite3"gem"jquery-rails"gem"draper"gem"rails",'4.1.0'gem"therubyracer"gem"uglifier"gem"rspec-rails"gem"capybara"gem"poltergeist"gem"launchy"运行

  9. ruby-on-rails - 如果没有可用标签,则运行标记规范或全部 - 2

    我将guard与rspec和cucumber一起使用。要连续运行选定的规范,我只需使用focus标记来确定我要处理的内容。但问题是,如果没有带有该标签的规范,我想运行所有规范。我该怎么做?注意::我知道所有RSpec选项。因此,请仅在阅读问题后回复。 最佳答案 我通过以下配置实现了您描述的行为:#torunonlyspecificspecs,add:focustothespec#describe"foo",:focusdo#OR#it"shouldfoo",:focusdoconfig.treat_symbols_as_metada

  10. ruby - Minitest 规范自定义匹配器 - 2

    我的测试中有一行:page.has_reply?("myreply").must_equaltrue为了使其更具可读性,我想使用自定义匹配器:page.must_have_reply"myreply"基于https://github.com/zenspider/minitest-matchers的文档我希望我需要编写一个看起来像这样的匹配器:defhave_reply(text)subject.has_css?('.comment_body',:text=>text)endMiniTest::Unit::TestCase.register_matcher:have_reply,:hav

随机推荐