A Git hook to validate your commit messages based on community standards.
$ git commit
Adding a cool feature
foobar foobar foobar,
foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar
1: Error: Message must use imperative present tense.
2: Error: Second line must be blank.
3: Error: Lines should be <= 72 chars. (76)
Commit anyway? [y/n/e] ▊
- Ruby >= 1.9 (OS X users already have this installed)
Install the gem:
$ gem install fit-commit
Install the hook in your Git repo:
$ fit-commit install
This creates a .git/hooks/commit-msg
script which will automatically check your Git commit messages.
- Line Length: All lines must be <= 72 chars (URLs excluded). First line should be <= 50 chars. Second line must be blank.
- Tense: Message must use imperative present tense: "Fix bug" and not "Fixed bug" or "Fixes bug."
- Subject Period: Do not end your subject line with a period.
- Capitalize Subject: Begin all subject lines with a capital letter.
- Frat House: No offensive content.
- WIP: Do not commit WIPs to shared branches (disabled by default)
Settings are read from these files in increasing precedence: /etc/fit_commit.yml
, $HOME/.fit_commit.yml
, config/fit_commit.yml
, ./.fit_commit.yml
.
These are the default settings that can be overridden:
---
Validators/LineLength:
Enabled: true
MaxLineLength: 72
SubjectWarnLength: 50
AllowLongUrls: true
Validators/Tense:
Enabled: true
Validators/SubjectPeriod:
Enabled: true
Validators/CapitalizeSubject:
Enabled: true
WarnOnWiplikes: true
Validators/Frathouse:
Enabled: true
Validators/Wip:
Enabled: false
The Enabled
property accepts multiple formats:
# true/false to enable/disable the validation (branch agnostic)
Validators/Foo:
Enabled: false
# Array of String or Regex matching each branch it's enabled on
Validators/Bar:
Enabled:
- main
- !ruby/regexp /\Afoo.+bar/
Create your custom validator as a FitCommit::Validators::Base
subclass:
module FitCommit
module Validators
class MyCustomValidator < Base
def validate_line(lineno, text)
if text =~ /sneak peak/i
add_error(lineno, "I think you mean 'sneak peek'.")
end
end
end
end
end
# A validator can also validate the commit message as a whole:
module FitCommit
module Validators
class MyCustomValidator < Base
def validate(lines)
if lines.none? { |line| line.text =~ /#\d+/ }
add_warning(lines.last.lineno, "Related issue not referenced.")
end
end
end
end
end
Require
the file and enable the validator in your config:
FitCommit:
Require:
- somedir/my_custom_validator.rb
Validators/MyCustomValidator:
Enabled: true
You can also publish your validator as a gem, and require it that way:
FitCommit:
Require:
- my-custom-validator-gem
Validators/MyCustomValidator:
Enabled: true
If others might find your validator useful, submit it as a Pull Request. If it's not useful for everyone, it can be disabled by default.
First set your global Git template directory:
$ git config --global init.templatedir '~/.git_template'
$ mkdir -p ~/.git_template/hooks
Now you can copy the hooks you want installed in new repos by default:
# From a repo where Fit Commit is already installed
$ cp .git/hooks/commit-msg ~/.git_template/hooks/commit-msg
To copy your default hooks into existing repos:
$ git init
Fit Commit can be run outside of a Git hook context with a simple shell script:
$ export GIT_BRANCH_NAME=branch_name
$ export COMMIT_MESSAGE_PATH=path/to/message
# Using Bundler
$ bundle exec ruby -e 'require "fit_commit"; FitCommit.run'
# Not using Bundler
$ rbenv exec ruby -rrubygems -e 'require "fit_commit"; FitCommit.run'
It exits with an error code if any errors are present, which will fail a build if it's part of a CI run.
Fit Commit aims to enforce community standards. The two influential guides are:
The Git community has largely (but not completely) coalesced around these standards. Chris Beams and the Pro Git book also provide good summaries on why we have them.
Fit Commit aims to be useful to everyone. If you can suggest an improvement to make it useful to more people, please open a GitHub Issue or Pull Request. See CONTRIBUTING.md for more info.
Author: Mike Foley
Inspiration taken from: Tim Pope, Jason Fox, Addam Hardy, pre-commit
Similar projects:
- gitlint (written in Python)
- fit-commit-js (Node.js package)