summaryrefslogtreecommitdiffstats
path: root/docs/index.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/index.md')
-rw-r--r--docs/index.md339
1 files changed, 247 insertions, 92 deletions
diff --git a/docs/index.md b/docs/index.md
index 3155b19..b735b6b 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,4 +1,4 @@
-# Intro
+# Introduction
Gitlint is a git commit message linter written in python: it checks your commit messages for style.
Great for use as a [commit-msg git hook](#using-gitlint-as-a-commit-msg-hook) or as part of your gating script in a
@@ -7,46 +7,55 @@ Great for use as a [commit-msg git hook](#using-gitlint-as-a-commit-msg-hook) or
<script type="text/javascript" src="https://asciinema.org/a/30477.js" id="asciicast-30477" async></script>
!!! note
- **Gitlint support for Windows is experimental**, and [there are some known issues](https://github.com/jorisroovers/gitlint/issues?q=is%3Aissue+is%3Aopen+label%3Awindows).
+ **Gitlint works on Windows**, but [there are some known issues](https://github.com/jorisroovers/gitlint/issues?q=is%3Aissue+is%3Aopen+label%3Awindows).
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](https://github.com/m1foley/fit-commit) (Ruby),
[node-commit-msg](https://github.com/clns/node-commit-msg) (Node.js) or [commitlint](http://marionebl.github.io/commitlint) (Node.js).
-## Features ##
+
+!!! important
+ **Gitlint requires Python 3.7 (or above). For Python 2.7 and Python 3.5 use `gitlint==0.14.0` (released 2020-10-24), for Python 3.6 `gitlint==0.18.0` (released 2022-11-16).**
+
+## Features
- **Commit message hook**: [Auto-trigger validations against new commit message right when you're committing](#using-gitlint-as-a-commit-msg-hook). Also [works with pre-commit](#using-gitlint-through-pre-commit).
- **Easily integrated**: Gitlint is designed to work [with your own scripts or CI system](#using-gitlint-in-a-ci-environment).
- **Sane defaults:** Many of gitlint's validations are based on
[well-known](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
-[community](http://addamhardy.com/2013/06/05/good-commit-messages-and-enforcing-them-with-git-hooks.html),
+[community](https://addamhardy.com/2013-06-05-good-commit-messages-and-enforcing-them-with-git-hooks),
[standards](http://chris.beams.io/posts/git-commit/), 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](configuration.md).
- - **Community contributed rules**: Conventions that are common but not universal [can be selectively enabled](contrib_rules).
+ - **Community contributed rules**: Conventions that are common but not universal [can be selectively enabled](contrib_rules.md).
- **User-defined rules:** Want to do more then what gitlint offers out of the box? Write your own [user defined rules](user_defined_rules.md).
- - **Broad python version support:** Gitlint supports python versions 2.7, 3.5+, PyPy2 and PyPy3.5.
- **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: actively maintained, high unit test coverage, integration tests,
- python code standards (pep8, pylint), good documentation, widely used, proven track record.
+ python code standards ([black](https://github.com/psf/black), [ruff](https://github.com/charliermarsh/ruff)),
+ good documentation, widely used, proven track record.
-# Getting Started
-## Installation
-```bash
+## Getting Started
+### Installation
+```sh
# Pip is recommended to install the latest version
pip install gitlint
-# macOS
-brew tap rockyluke/devops
-brew install gitlint
+# Alternative: by default, gitlint is installed with pinned dependencies.
+# To install gitlint with looser dependency requirements, only install gitlint-core.
+pip install gitlint-core
-# Ubuntu
-apt-get install gitlint
+# Community maintained packages:
+brew install gitlint # Homebrew (macOS)
+sudo port install gitlint # Macports (macOS)
+apt-get install gitlint # Ubuntu
+# Other package managers, see https://repology.org/project/gitlint/versions
# Docker: https://hub.docker.com/r/jorisroovers/gitlint
-docker run -v $(pwd):/repo jorisroovers/gitlint
+docker run --ulimit nofile=1024 -v $(pwd):/repo jorisroovers/gitlint
+# NOTE: --ulimit is required to work around a limitation in Docker
+# Details: https://github.com/jorisroovers/gitlint/issues/129
```
-## Usage
+### Usage
```sh
# Check the last commit message
gitlint
@@ -64,7 +73,7 @@ gitlint install-hook
```
Output example:
-```bash
+```sh
$ 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 "
@@ -77,11 +86,24 @@ $ cat examples/commit-message-2 | gitlint
!!! note
The returned exit code equals the number of errors found. [Some exit codes are special](index.md#exit-codes).
-# Configuration
+### Shell completion
+
+```sh
+# Bash: add to ~/.bashrc
+eval "$(_GITLINT_COMPLETE=bash_source gitlint)"
+
+# Zsh: add to ~/.zshrc
+eval "$(_GITLINT_COMPLETE=zsh_source gitlint)"
+
+# Fish: add to ~/.config/fish/completions/foo-bar.fish
+eval (env _GITLINT_COMPLETE=fish_source gitlint)
+```
+
+## Configuration
For in-depth documentation of general and rule-specific configuration options, have a look at the [Configuration](configuration.md) and [Rules](rules.md) pages.
-Short example ```.gitlint``` file ([full reference](configuration.md)):
+Short example `.gitlint` file ([full reference](configuration.md)):
```ini
[general]
@@ -89,7 +111,7 @@ Short example ```.gitlint``` file ([full reference](configuration.md)):
# their id or by their full name
ignore=body-is-missing,T3
-# Ignore any data send to gitlint via stdin
+# Ignore any data sent to gitlint via stdin
ignore-stdin=true
# Configure title-max-length rule, set title length to 80 (72 = default)
@@ -103,7 +125,7 @@ line-length=123
Example use of flags:
-```bash
+```sh
# Change gitlint's verbosity.
$ gitlint -v
# Ignore certain rules
@@ -129,9 +151,11 @@ Options:
current working directory]
-C, --config FILE 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.g.: -c T1.line-length=80). Flag can be
+ used multiple times to set multiple config values.
+ --commit TEXT Hash (SHA) of specific commit to lint.
+ --commits TEXT The range of commits (refspec or comma-separated
+ hashes) 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).
@@ -140,12 +164,14 @@ Options:
--msg-filename FILENAME Path to a file containing a commit-msg.
--ignore-stdin Ignore any stdin data. Useful for running in CI
server.
- --staged Read staged commit meta-info from the local
- repository.
- -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.
+ --staged Attempt smart guesses about meta info (like
+ author name, email, branch, changed files, etc)
+ for staged commits.
+ --fail-without-commits Hard fail when the target commit range is empty.
+ -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.
@@ -154,19 +180,20 @@ 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]
+ run-hook Runs the gitlint commit-msg hook.
uninstall-hook Uninstall gitlint commit-msg hook.
When no COMMAND is specified, gitlint defaults to 'gitlint lint'.
```
-# Using gitlint as a commit-msg hook ##
+## 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
+You can also install gitlint as a git `commit-msg` hook so that gitlint checks your commit messages automatically
after each commit.
-```bash
+```sh
gitlint install-hook
# To remove the hook
gitlint uninstall-hook
@@ -174,13 +201,13 @@ gitlint uninstall-hook
!!! important
- Gitlint cannot work together with an existing hook. If you already have a ```.git/hooks/commit-msg```
- file in your local repository, gitlint will refuse to install the ```commit-msg``` hook. Gitlint will also only
+ Gitlint cannot work together with an existing hook. If you already have a `.git/hooks/commit-msg`
+ 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.
If you're looking to use gitlint in conjunction with other hooks, you should consider
[using gitlint with pre-commit](#using-gitlint-through-pre-commit).
-# Using gitlint through [pre-commit](https://pre-commit.com)
+## Using gitlint through [pre-commit](https://pre-commit.com)
`gitlint` can be configured as a plugin for the `pre-commit` git hooks
framework. Simply add the configuration to your `.pre-commit-config.yaml`:
@@ -198,10 +225,10 @@ pre-commit install --hook-type commit-msg
```
!!! important
- It's important that you run ```pre-commit install --hook-type commit-msg```, even if you've already used
- ```pre-commit install``` before. ```pre-commit install``` does **not** install commit-msg hooks by default!
+ It's important that you run `pre-commit install --hook-type commit-msg`, even if you've already used
+ `pre-commit install` before. `pre-commit install` does **not** install commit-msg hooks by default!
-To manually trigger gitlint using ```pre-commit``` for your last commit message, use the following command:
+To manually trigger gitlint using `pre-commit` for your last commit message, use the following command:
```sh
pre-commit run gitlint --hook-stage commit-msg --commit-msg-filename .git/COMMIT_EDITMSG
```
@@ -211,16 +238,49 @@ In case you want to change gitlint's behavior, you should either use a `.gitlint
your `.pre-commit-config.yaml` file like so:
```yaml
- repo: https://github.com/jorisroovers/gitlint
- rev: # Fill in a tag / sha here
+ rev: # Fill in a tag / sha here (e.g. v0.18.0)
hooks:
- id: gitlint
- stages: [commit-msg]
- entry: gitlint
args: [--contrib=CT1, --msg-filename]
```
-# Using gitlint in a CI environment ##
-By default, when just running ```gitlint``` without additional parameters, gitlint lints the last commit in the current
+!!! important
+
+ You need to add `--msg-filename` at the end of your custom `args` list as the gitlint-hook will fail otherwise.
+
+
+### gitlint and pre-commit in CI
+gitlint also supports a `gitlint-ci` pre-commit hook that can be used in CI environments.
+
+Configure it like so:
+```yaml
+- repo: https://github.com/jorisroovers/gitlint
+ rev: # insert ref, e.g. v0.18.0
+ hooks:
+ - id: gitlint # this is the regular commit-msg hook
+ - id: gitlint-ci # hook for CI environments
+```
+
+And invoke it in your CI environment like this:
+
+```sh
+pre-commit run --hook-stage manual gitlint-ci
+```
+
+By default this will only lint the latest commit.
+If you want to lint more commits you can modify the `gitlint-ci` hook like so:
+
+```yaml
+- repo: https://github.com/jorisroovers/gitlint
+ rev: # insert ref, e.g. v0.18.0
+ hooks:
+ - id: gitlint
+ - id: gitlint-ci
+ args: [--debug, --commits, mybranch] # enable debug mode, lint all commits in mybranch
+```
+
+## Using gitlint in a CI environment
+By default, when just running `gitlint` without additional parameters, gitlint lints the last commit in the current
working directory.
This makes it easy to use gitlint in a CI environment (Jenkins, TravisCI, Github Actions, pre-commit, CircleCI, Gitlab, etc).
@@ -229,59 +289,76 @@ In fact, this is exactly what we do ourselves: on every commit,
This will cause the build to fail when we submit a bad commit message.
Alternatively, gitlint will also lint any commit message that you feed it via stdin like so:
-```bash
+```sh
# 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 ```--pretty``` argument.
+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 `--pretty` argument.
-## Linting a range of commits ##
+## Linting specific commits or branches
-_Introduced in gitlint v0.9.0 (experimental in v0.8.0)_
+Gitlint can lint specific commits using `--commit`:
+```sh
+gitlint --commit 019cf40580a471a3958d3c346aa8bfd265fe5e16
+gitlint --commit 019cf40 # short SHAs work too
+gitlint --commit HEAD~2 # as do special references
+gitlint --commit mybranch # lint latest commit on a branch
+```
-Gitlint allows users to commit a number of commits at once like so:
+You can also lint multiple commits using `--commits` (plural):
-```bash
+```sh
# 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"
+# Lint all commits on a branch
+gitlint --commits mybranch
+# Lint all commits that are different between a branch and your main branch
+gitlint --commits "main..mybranch"
+# Use git's special references
+gitlint --commits "origin/main..HEAD"
+
+# You can also pass multiple, comma separated commit hashes:
+gitlint --commits 019cf40,c50eb150,d6bc75a
+# These can include special references as well
+gitlint --commits HEAD~1,mybranch-name,origin/main,d6bc75a
+# You can also lint a single commit with --commits:
+gitling --commits 019cf40,
```
-The ```--commits``` flag takes a **single** refspec argument or commit range. Basically, any range that is understood
+The `--commits` flag takes a **single** refspec argument or commit range. Basically, any range that is understood
by [git rev-list](https://git-scm.com/docs/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.
+Alternatively, you can pass `--commits` a comma-separated list of commit hashes (both short and full-length SHAs work,
+as well as special references such as `HEAD` and branch names).
+Gitlint will treat these as pointers to **single** commits and lint these in the order you passed.
+`--commits` also accepts a single commit SHA with a trailing comma.
-```bash
-#!/bin/bash
+For cases where the `--commits` option doesn't provide the flexibility you need, you can always use a simple shell
+script to lint an arbitrary set of commits, like shown in the example below.
-for commit in $(git rev-list master); do
- commit_msg=$(git log -1 --pretty=%B $commit)
- echo "$commit"
- echo "$commit_msg" | gitlint
+```sh
+#!/bin/sh
+
+for commit in $(git rev-list my-branch); do
+ echo "Commit $commit"
+ gitlint --commit $commit
echo "--------"
done
```
!!! note
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.
+ This means you'll incur the gitlint startup time once per commit, making it 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), v0.9.0 (fixup, squash) and v0.13.0 (revert)_
+## Merge, fixup, squash and revert commits
+_Introduced in gitlint v0.7.0 (merge), v0.9.0 (fixup, squash), v0.13.0 (revert) and v0.18.0 (fixup=amend)_
-**Gitlint ignores merge, revert, fixup and squash commits by default.**
+**Gitlint ignores merge, revert, fixup, and squash commits by default.**
For merge and revert commits, the rationale for ignoring them is
that most users keep git's default messages for these commits (i.e *Merge/Revert "[original commit message]"*).
@@ -291,28 +368,26 @@ For example, a common case is that *"Merge:"* being auto-prepended triggers a
[title-max-length](rules.md#t1-title-max-length) violation. Most users don't want this, so we disable linting
on Merge and Revert commits by default.
-For [squash](https://git-scm.com/docs/git-commit#git-commit---squashltcommitgt) and [fixup](https://git-scm.com/docs/git-commit#git-commit---fixupltcommitgt) commits, the rationale is that these are temporary
+For [squash](https://git-scm.com/docs/git-commit#git-commit---squashltcommitgt) and [fixup](https://git-scm.com/docs/git-commit#git-commit---fixupltcommitgt) (including [fixup=amend](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---fixupamendrewordltcommitgt)) 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
+short-lived and not intended to make it into the final commit history. In addition, by prepending *"fixup!"*,
+*"amend!"* or *"squash!"* to your commit message, certain gitlint rules might be violated
(e.g. [title-max-length](rules.md#t1-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
-general ```ignore-merge-commits```, ```ignore-revert-commits```, ```ignore-fixup-commits``` or
-```ignore-squash-commits``` option to ```false```
+general `ignore-merge-commits`, `ignore-revert-commits`, `ignore-fixup-commits`, `ignore-fixup-amend-commits` or
+`ignore-squash-commits` option to `false`
[using one of the various ways to configure gitlint](configuration.md).
-# Ignoring commits ##
-_Introduced in gitlint v0.10.0_
+## Ignoring commits
-You can configure gitlint to ignore specific commits.
+You can configure gitlint to ignore specific commits or parts of a commit.
-One way to do this, is to by [adding a gitline-ignore line to your commit message](configuration.md#commit-specific-config).
+One way to do this, is by [adding a gitlint-ignore line to your commit message](configuration.md#commit-specific-config).
If you have a case where you want to ignore a certain type of commits all-together, you can
use gitlint's *ignore* rules.
-Here's an example gitlint file that configures gitlint to ignore rules ```title-max-length``` and ```body-min-length```
-for all commits with a title starting with *"Release"*.
+Here's a few examples snippets from a `.gitlint` file:
```ini
[ignore-by-title]
@@ -326,15 +401,95 @@ ignore=title-max-length,body-min-length
# Match commits message bodies that have a line that contains 'release'
regex=(.*)release(.*)
ignore=all
+
+[ignore-by-author-name]
+# Match commits by author name (e.g. ignore all rules when a commit is made by dependabot)
+regex=dependabot
+ignore=all
```
+If you just want to ignore certain lines in a commit, you can do that using the
+[ignore-body-lines](rules.md#i3-ignore-body-lines) rule.
+
+```ini
+# Ignore all lines that start with 'Co-Authored-By'
+[ignore-body-lines]
+regex=^Co-Authored-By
+```
+
+!!! warning
+
+ When ignoring specific lines, gitlint will no longer be aware of them while applying other rules.
+ This can sometimes be confusing for end-users, especially as line numbers of violations will typically no longer
+ match line numbers in the original commit message. Make sure to educate your users accordingly.
+
!!! note
- Right now it's not possible to write user-defined ignore rules to handle more complex use-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](https://github.com/jorisroovers/gitlint/issues).
+ If you want to implement more complex ignore rules according to your own logic, you can do so using [user-defined
+ configuration rules](user_defined_rules.md#configuration-rules).
+
+## Named Rules
+
+Introduced in gitlint v0.14.0
+
+Named rules allow you to have multiple of the same rules active at the same time, which allows you to
+enforce the same rule multiple times but with different options. Named rules are so-called because they require an
+additional unique identifier (i.e. the rule *name*) during configuration.
+
+!!! warning
+
+ Named rules is an advanced topic. It's easy to make mistakes by defining conflicting instances of the same rule.
+ For example, by defining 2 `body-max-line-length` rules with different `line-length` options, you obviously create
+ a conflicting situation. Gitlint does not do any resolution of such conflicts, it's up to you to make sure
+ any configuration is non-conflicting. So caution advised!
+
+Defining a named rule is easy, for example using your `.gitlint` file:
+
+```ini
+# By adding the following section, you will add a second instance of the
+# title-must-not-contain-word (T5) rule (in addition to the one that is enabled
+# by default) with the name 'extra-words'.
+[title-must-not-contain-word:extra-words]
+words=foo,bar
+
+# So the generic form is
+# [<rule-id-or-name>:<your-chosen-name>]
+# Another example, referencing the rule type by id
+[T5:more-words]
+words=hur,dur
+
+# You can add as many additional rules and you can name them whatever you want
+# The only requirement is that names cannot contain whitespace or colons (:)
+[title-must-not-contain-word:This-Can_Be*Whatever$YouWant]
+words=wonderwoman,batman,power ranger
+```
+
+When executing gitlint, you will see the violations from the default `title-must-not-contain-word (T5)` rule, as well as
+the violations caused by the additional Named Rules.
+
+```sh
+$ gitlint
+1: T5 Title contains the word 'WIP' (case-insensitive): "WIP: foo wonderwoman hur bar"
+1: T5:This-Can_Be*Whatever$YouWant Title contains the word 'wonderwoman' (case-insensitive): "WIP: foo wonderwoman hur bar"
+1: T5:extra-words Title contains the word 'foo' (case-insensitive): "WIP: foo wonderwoman hur bar"
+1: T5:extra-words Title contains the word 'bar' (case-insensitive): "WIP: foo wonderwoman hur bar"
+1: T5:more-words Title contains the word 'hur' (case-insensitive): "WIP: foo wonderwoman hur bar"
+```
+
+Named rules are further treated identical to all other rules in gitlint:
+
+- You can reference them by their full name, when e.g. adding them to your `ignore` configuration
+```ini
+# .gitlint file example
+[general]
+ignore=T5:more-words,title-must-not-contain-word:extra-words
+```
+
+- You can use them to instantiate multiple of the same [user-defined rule](user_defined_rules.md)
+- You can configure them using [any of the ways you can configure regular gitlint rules](configuration.md)
+
-# Exit codes ##
+## Exit codes
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.
@@ -344,8 +499,8 @@ of violations counted by the exit code is 252. Note that gitlint does not have a
it can detect, it will just always return with exit code 252 when the number of violations is greater than or equal
to 252.
-Exit Code | Description
------------|------------------------------------------------------------
-253 | Wrong invocation of the ```gitlint``` command.
-254 | Something went wrong when invoking git.
-255 | Invalid gitlint configuration
+| Exit Code | Description |
+| --------- | ------------------------------------------ |
+| 253 | Wrong invocation of the `gitlint` command. |
+| 254 | Something went wrong when invoking git. |
+| 255 | Invalid gitlint configuration |