Line and Commit Rules
Gitlint has 2 types of user-defined rules for linting commit messages:
CommitRule
: applied once per commitLineRule
: applied on a line-by line basis (targetting either the commit message title or every line in the commit message body).
The benefit of a CommitRule
is that it allows for more complex checks that span multiple lines and/or checks
that should only be done once per commit. Conversely a LineRule
allows for greater code re-use and implementation simplicity.
While every LineRule
can be implemented as a CommitRule
, the opposite is not true.
Examples¶
In terms of code, writing your own CommitRule
or LineRule
is very similar.
The only 2 differences between a CommitRule
and a LineRule
are the parameters of the validate(...)
method and the extra
target
attribute that LineRule
requires.
Consider the following CommitRule
that can be found in examples/my_commit_rules.py:
- When extending from
CommitRule
,validate(...)
takes a singlecommit
argument.
Contrast this with the following LineRule
that can be found in examples/my_line_rules.py:
- In this example, we set to
target = CommitMessageTitle
indicating that thisLineRule
should only be applied once to the commit message title.
The alternative value fortarget
isCommitMessageBody
, in which case gitlint will apply your rule to every line in the commit message body. - When extending from
LineRule
,validate(...)
get theline
against which they are applied as the first argument and thecommit
object of which the line is part of as second.
You might also noticed the extra options_spec
class attribute which allows you to make your rules configurable.
Options are not unique to LineRule
s, they can also be used by CommitRule
s.
Commit object¶
Both CommitRule
s and LineRule
s take a commit
object in their validate(...)
methods.
The table below outlines the various attributes of that commit object that can be used during validation.
Property | Type | Description |
---|---|---|
commit |
GitCommit |
Python object representing the commit |
commit.message |
GitCommitMessage |
Python object representing the commit message |
commit.message.original |
str |
Original commit message as returned by git |
commit.message.full |
str |
Full commit message, without comments (lines starting with # removed). |
commit.message.title |
str |
Title/subject of the commit message: the first line |
commit.message.body |
str[] |
List of lines in the body of the commit message (i.e. starting from the second line) |
commit.author_name |
s#!python tr |
Name of the author, result of git log --pretty=%aN |
commit.author_email |
str |
Email of the author, result of git log --pretty=%aE |
commit.date |
datetime.datetime |
Python datetime object representing the time of commit |
commit.is_merge_commit |
bool |
Boolean indicating whether the commit is a merge commit or not. |
commit.is_revert_commit |
bool |
Boolean indicating whether the commit is a revert commit or not. |
commit.is_fixup_commit |
bool |
Boolean indicating whether the commit is a fixup commit or not. |
commit.is_fixup_amend_commit |
bool |
Boolean indicating whether the commit is a (fixup) amend commit or not. |
commit.is_squash_commit |
bool |
Boolean indicating whether the commit is a squash cosmmit or not. |
commit.parents |
str[] |
List of parent commit sha s (only for merge commits). |
commit.changed_files |
str[] |
List of files changed in the commit (relative paths). |
commit.changed_files_stats |
dict[str, GitChangedFilesStats] |
Dictionary mapping the changed files to a GitChangedFilesStats objects |
commit.changed_files_stats["a/b.txt"].filepath |
pathlib.Path |
Relative path (compared to repo root) of the file that was changed. |
commit.changed_files_stats["a/b.txt"].additions |
int |
Number of additions in the file. |
commit.changed_files_stats["a/b.txt"].deletions |
int |
Number of deletions in the file. |
commit.branches |
str[] |
List of branch names the commit is part of |
commit.context |
GitContext |
Object pointing to the bigger git context that the commit is part of |
commit.context.current_branch |
str |
Name of the currently active branch (of local repo) |
commit.context.repository_path |
str |
Absolute path pointing to the git repository being linted |
commit.context.commits |
GitCommit[] |
List of commits gitlint is acting on, NOT all commits in the repo. |