Gitlint is a git commit message linter written in python: it checks your commit messages for style.
Gitlint is currently not supported on Windows.
Also, gitlint is not the only git commit message linter out there, if you are looking for an alternative written in a different language, have a look at fit-commit (Ruby), node-commit-msg (Node.js) or commitlint (Node.js).
- Commit message hook: Auto-trigger validations against new commit message right when you're committing.
- Easily integrated: Gitlint will validate any git commit message you give it via standard input. Perfect for integration with your own scripts or CI system.
- Sane defaults: Many of gitlint's validations are based on well-known, community, standards, others are based on checks that we've found useful throughout the years.
- Easily configurable: Gitlint has sane defaults, but you can also easily customize it to your own liking.
- User-defined Rules: Want to do more then what gitlint offers out of the box? Write your own user defined rules.
- Broad python version support: Gitlint supports python versions 2.6, 2.7, 3.3+ and PyPy2.
- Full unicode support: Lint your Russian, Chinese or Emoji commit messages with ease!
- Production-ready: Gitlint checks a lot of the boxes you're looking for: high unit test coverage, integration tests, python code standards (pep8, pylint), good documentation, proven track record.
# Install gitlint pip install gitlint # On macOS (recommended to use pip for the latest version) brew tap rockyluke/devops brew install gitlint # Check the last commit message gitlint # Alternatively, pipe a commit message to gitlint: cat examples/commit-message-1 | gitlint # or git log -1 --pretty=%B | gitlint # Or read the commit-msg from a file, like so: gitlint --msg-filename examples/commit-message-2 # To install a gitlint as a commit-msg git hook: gitlint install-hook
$ cat examples/commit-message-2 | gitlint 1: T1 Title exceeds max length (134>80): "This is the title of a commit message that is over 80 characters and contains hard tabs and trailing whitespace and the word wiping " 1: T2 Title has trailing whitespace: "This is the title of a commit message that is over 80 characters and contains hard tabs and trailing whitespace and the word wiping " 1: T4 Title contains hard tab characters (\t): "This is the title of a commit message that is over 80 characters and contains hard tabs and trailing whitespace and the word wiping " 2: B4 Second line is not empty: "This line should not contain text" 3: B1 Line exceeds max length (125>80): "Lines typically need to have a max length, meaning that they can't exceed a preset number of characters, usually 80 or 120. " 3: B2 Line has trailing whitespace: "Lines typically need to have a max length, meaning that they can't exceed a preset number of characters, usually 80 or 120. " 3: B3 Line contains hard tab characters (\t): "Lines typically need to have a max length, meaning that they can't exceed a preset number of characters, usually 80 or 120. "
The returned exit code equals the number of errors found. Some exit codes are special.
For a list of available rules and their configuration options, have a look at the Rules page.
The Configuration page explains how you can modify gitlint's runtime behavior via command-line
.gitlint configuration file or on a per commit basis.
As a simple example, you can modify gitlint's verbosity using the
-v flag, like so:
$ cat examples/commit-message-2 | gitlint -v 1: T1 1: T2 [removed output] $ cat examples/commit-message-2 | gitlint -vv 1: T1 Title exceeds max length (134>80) 1: T2 Title has trailing whitespace 1: T4 Title contains hard tab characters (\t) [removed output] $ cat examples/commit-message-2 | gitlint -vvv 1: T1 Title exceeds max length (134>80): "This is the title of a commit message that is over 80 characters and contains hard tabs and trailing whitespace and the word wiping " 1: T2 Title has trailing whitespace: "This is the title of a commit message that is over 80 characters and contains hard tabs and trailing whitespace and the word wiping " [removed output]
The default verbosity is
Other commands and variations:
$ gitlint --help Usage: gitlint [OPTIONS] COMMAND [ARGS]... Git lint tool, checks your git commit messages for styling issues Options: --target DIRECTORY Path of the target git repository. [default: current working directory] -C, --config PATH Config file location [default: .gitlint] -c TEXT Config flags in format <rule>.<option>=<value> (e.g.: -c T1.line-length=80). Flag can be used multiple times to set multiple config values. --commits TEXT The range of commits to lint. [default: HEAD] -e, --extra-path PATH Path to a directory or python module with extra user-defined rules --ignore TEXT Ignore rules (comma-separated by id or name). --msg-filename FILENAME Path to a file containing a commit-msg -v, --verbose Verbosity, more v's for more verbose output (e.g.: -v, -vv, -vvv). [default: -vvv] -s, --silent Silent mode (no output). Takes precedence over -v, -vv, -vvv. -d, --debug Enable debugging output. --version Show the version and exit. --help Show this message and exit. Commands: generate-config Generates a sample gitlint config file. install-hook Install gitlint as a git commit-msg hook. lint Lints a git repository [default command] uninstall-hook Uninstall gitlint commit-msg hook. When no COMMAND is specified, gitlint defaults to 'gitlint lint'.
Using gitlint as a commit-msg hook
Introduced in gitlint v0.4.0
You can also install gitlint as a git
commit-msg hook so that gitlint checks your commit messages automatically
after each commit.
gitlint install-hook # To remove the hook gitlint uninstall-hook
Gitlint cannot work together with an existing hook. If you already have a
file in your local repository, gitlint will refuse to install the
commit-msg hook. Gitlint will also only
uninstall unmodified commit-msg hooks that were installed by gitlint.
Using gitlint through pre-commit
gitlint can be configured as a plugin for the
pre-commit git hooks
framework. Simply add the configuration to your
- repo: https://github.com/jorisroovers/gitlint rev: # Fill in a tag / sha here hooks: - id: gitlint
Using gitlint in a CI environment
By default, when just running
gitlint without additional parameters, gitlint lint the last commit in the current
This makes it easy to add gitlint to a check script that is run in a CI environment (Jenkins, TravisCI, pre-commit, CircleCI, etc). In fact, this is exactly what we do ourselves: on every commit, we run gitlint as part of our travisCI tests. This will cause the build to fail when we submit a bad commit message.
Versions prior to gitlint 0.9.0 required a TTY to be attached to STDIN for this to work, this is no longer required now.
Alternatively, gitlint will also lint any commit message that you feed it via stdin like so:
# lint the last commit message git log -1 --pretty=%B | gitlint # lint a specific commit: 62c0519 git log -1 --pretty=%B 62c0519 | gitlint
Note that gitlint requires that you specify
--pretty=%B (=only print the log message, not the metadata),
future versions of gitlint might fix this and not require the
Linting a range of commits
Introduced in gitlint v0.9.0 (experimental in v0.8.0)
Gitlint allows users to commit a number of commits at once like so:
# Lint a specific commit range: gitlint --commits 019cf40...d6bc75a # You can also use git's special references: gitlint --commits origin..HEAD # Or specify a single specific commit in refspec format, like so: gitlint --commits 019cf40^...019cf40
--commits flag takes a single refspec argument or commit range. Basically, any range that is understood
by git rev-list as a single argument will work.
Prior to v0.8.1 gitlint didn't support this feature. However, older versions of gitlint can still lint a range or set
of commits at once by creating a simple bash script that pipes the commit messages one by one into gitlint. This
approach can still be used with newer versions of gitlint in case
--commits doesn't provide the flexibility you
are looking for.
#!/bin/bash for commit in $(git rev-list master); do commit_msg=$(git log -1 --pretty=%B $commit) echo "$commit" echo "$commit_msg" | gitlint echo "--------" done
One downside to this approach is that you invoke gitlint once per commit vs. once per set of commits.
This means you'll incur the gitlint startup time once per commit, making this approach rather slow if you want to
lint a large set of commits. Always use
--commits if you can to avoid this performance penalty.
Merge, fixup and squash commits
Introduced in gitlint v0.7.0 (merge commits) and gilint v0.9.0 (fixup, squash)
Gitlint ignores merge, fixup and squash commits by default.
For merge commits, the rationale for ignoring them is that in many cases merge commits are not created by users themselves but by tools such as github, gerrit and others. These tools often generate merge commit messages that violate gitlint's set of rules (a common example is "Merge:" being auto-prepended which can trigger a title-max-length violation) and it's not always convenient or desired to change those.
For squash and fixup commits, the rationale is that these are temporary commits that will be squashed into a different commit, and hence the commit messages for these commits are very short-lived and not intended to make it into the final commit history. In addition, by prepending "fixup!" or "squash!" to your commit message, certain gitlint rules might be violated (e.g. title-max-length) which is often undesirable.
In case you do want to lint these commit messages, you can disable this behavior by setting the
ignore-squash-commits option to
using one of the various ways to configure gitlint.
Introduced in gitlint v0.10.0
Gitlint allows you to ignore specific rules for specific commits.
One way to do this, is to by adding a gitline-ignore line to your commit message.
If you have a case where you want to ignore a certain type of commits all-together, you can
use gitlint's ignore rules to do so.
Here's an example gitlint file that configures gitlint to ignore rules
for all commits with a title starting with "Release".
[ignore-by-title] # Match commit titles starting with Release regex=^Release(.*) ignore=title-max-length,body-min-length # ignore all rules by setting ignore to 'all' # ignore=all [ignore-by-title] # Match commits message bodies that have a line that contains 'release' regex=(.*)release(.*) ignore=all
Right now it's not possible to write user-defined ignore rules to handle more complex user-cases. This is however something that we'd like to implement in a future version. If this is something you're interested in please let us know by opening an issue.
Gitlint uses the exit code as a simple way to indicate the number of violations found. Some exit codes are used to indicate special errors as indicated in the table below.
Because of these special error codes and the fact that bash only supports exit codes between 0 and 255, the maximum number of violations counted by the exit code is 252. Note that gitlint does not have a limit on the number of violations it can detect, it will just always return with exit code 252 when the number of violations is greater than or equal to 252.
|253||Wrong invocation of the
|254||Something went wrong when invoking git.|
|255||Invalid gitlint configuration|