Contributors:
Special thanks to all contributors for this release, in particular [mrshu](https://github.com/mrshu), [glasserc](https://github.com/glasserc), [strk](https://github.com/strk), [chgl](https://github.com/chgl), [melg8](https://github.com/melg8) and [sigmavirus24](https://github.com/sigmavirus24).
General
- **IMPORTANT: Gitlint 0.14.x will be the last gitlint release to support Python 2.7 and Python 3.5, as [both are EOL](https://endoflife.date/python) which makes it difficult to keep supporting them.**
- Python 3.9 support
- [Named Rules](https://jorisroovers.github.io/gitlint/rules/named_rules/) allow users to have multiple instances of the same rule active at the same time. This is useful when you want to enforce the same rule multiple times but with different options ([#113](https://github.com/jorisroovers/gitlint/issues/113), [#66](https://github.com/jorisroovers/gitlint/issues/66))
- [User-defined Configuration Rules](https://jorisroovers.github.io/gitlint/rules/user_defined_rules/configuration_rules/) allow users to dynamically change gitlint's configuration and/or the commit *before* any other rules are applied.
- The `commit-msg` hook has been re-written in Python (it contained a lot of Bash before), fixing a number of platform specific issues. Existing users will need to reinstall their hooks (`gitlint uninstall-hook; gitlint install-hook`) to make use of this.
- Most general options can now be set through environment variables (e.g. set the `general.ignore` option via `GITLINT_IGNORE=T1,T2`). The list of available environment variables can be found in the [configuration documentation](https://jorisroovers.github.io/gitlint/configuration).
- Users can now use `self.log.debug("my message")` for debugging purposes in their user-defined rules. Debug messages will show up when running `gitlint --debug`.
- **Breaking**: User-defined rule id's can no longer start with 'I', as those are reserved for [built-in gitlint ignore rules](https://jorisroovers.github.io/gitlint/rules/builtin_rules/#i1-ignore-by-title).
- New `RegexOption` rule [option type for use in user-defined rules](https://jorisroovers.github.io/gitlint/rules/user_defined_rules/options/). By using the `RegexOption`, regular expressions are pre-validated at gitlint startup and compiled only once which is much more efficient when linting multiple commits.
Rules
- **New Rule**: [title-min-length](https://jorisroovers.github.io/gitlint/rules/builtin_rules/#t8-title-min-length) enforces a minimum length on titles (default: 5 chars) ([138](https://github.com/jorisroovers/gitlint/issues/138))
- **New Rule**: [body-match-regex](https://jorisroovers.github.io/gitlint/rules/builtin_rules/#b8-body-match-regex) allows users to enforce that the commit-msg body matches a given regex ([130](https://github.com/jorisroovers/gitlint/issues/130))
- **New Rule**: [ignore-body-lines](https://jorisroovers.github.io/gitlint/rules/builtin_rules/#i3-ignore-body-lines) allows users to
[ignore parts of a commit](https://jorisroovers.github.io/gitlint/ignoring_commits/) by matching a regex against
the lines in a commit message body ([126](https://github.com/jorisroovers/gitlint/issues/126))
Contrib Rules
- Added 'ci' and 'build' to conventional commit types ([135](https://github.com/jorisroovers/gitlint/issues/135))
Bugfixes
- Improved UTF-8 fallback on Windows (ongoing - [96](https://github.com/jorisroovers/gitlint/issues/96))
- Windows users can now use the 'edit' function of the `commit-msg` hook ([94](https://github.com/jorisroovers/gitlint/issues/94))
- Doc update: Users should use `--ulimit nofile=1024` when invoking gitlint using Docker ([129](https://github.com/jorisroovers/gitlint/issues/129))
- The `commit-msg` hook was broken in Ubuntu's gitlint package due to a python/python3 mismatch ([127](https://github.com/jorisroovers/gitlint/issues/127))
- Better error message when no git username is set ([149](https://github.com/jorisroovers/gitlint/issues/149))
- Options can now actually be set to `None` (from code) to make them optional.
- Ignore rules no longer have `"None"` as default regex, but an empty regex - effectively disabling them by default (as intended).
Development
- Minor performance improvements (removed some unnecessary regex matching),
- Test improvements,
- Improved debug logging,
- CI runs on pull requests
- PR request template