The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Git::Hooks::CheckLog - Git::Hooks plugin to enforce commit log policies

VERSION

version 3.6.0

SYNOPSIS

As a Git::Hooks plugin you don't use this Perl module directly. Instead, you may configure it in a Git configuration file like this:

  [githooks]

    # Enable the plugin
    plugin = CheckLog

    # These users are exempt from all checks
    admin = joe molly

  [githooks "checklog"]

    # The title line of commit messages must have at most 60 characters.
    title-max-width = 60

    # The title line of commit messages must not end in a period.
    title-period = deny

    # The lines in the body of commit messages must have at most 80 characters.
    body-max-width = 80

    # Enable spell checking of the commit messages.
    spelling = true

    # Use Brazilian Portuguese dictionary for spell checking
    spelling-lang = pt_BR

    # Rejects commits with messages containing the string "This reverts commit
    # <SHA-1>", if SHA-1 refers to a merge commit. Reverting a merge commit has
    # unexpected consequences, so that it's better to avoid it if at all
    # possible.
    deny-merge-revert = true

DESCRIPTION

This Git::Hooks plugin hooks itself to the hooks below to enforce policies on the commit log messages.

  • commit-msg, applypatch-msg

    This hook is invoked during the commit, to check if the commit log message complies.

  • update

    This hook is invoked multiple times in the remote repository during git push, once per branch being updated, to check if the commit log messages of all commits being pushed comply.

  • pre-receive

    This hook is invoked once in the remote repository during git push, to check if the commit log messages of all commits being pushed comply.

  • ref-update

    This hook is invoked when a direct push request is received by Gerrit Code Review, to check if the commit log messages of all commits being pushed comply.

  • commit-received

    This hook is invoked when a push request is received by Gerrit Code Review to create a change for review, to check if the commit log messages of all commits being pushed comply.

  • submit

    This hook is invoked when a change is submitted in Gerrit Code Review, to check if the commit log messages of all commits being pushed comply.

  • patchset-created

    This hook is invoked when a push request is received by Gerrit Code Review for a virtual branch (refs/for/*), to check if the commit log messages of all commits being pushed comply.

Projects using Git, probably more than projects using any other version control system, have a tradition of establishing policies on the format of commit log messages. The REFERENCES section below lists some of the most important.

This plugin allows one to enforce most of the established policies. The default configuration already enforces the most common ones.

To enable it you should add it to the githooks.plugin configuration option:

    [githooks]
      plugin = CheckLog

NAME

Git::Hooks::CheckLog - Git::Hooks plugin to enforce commit log policies

CONFIGURATION

The plugin is configured by the following git options under the githooks.checklog subsection.

It can be disabled for specific references via the githooks.ref and githooks.noref options about which you can read in the Git::Hooks documentation.

title-required BOOL

The first line of a Git commit log message is usually called the 'title'. It must be separated by the rest of the message (it's 'body') by one empty line. This option, which is true by default, makes the plugin check if there is a proper title in the log message.

title-max-width INT

This option specifies a limit to the width of the title's in characters. It's 50 by default. If you set it to 0 the plugin imposes no limit on the title's width.

title-period [deny|allow|require]

This option defines the policy regarding the title's ending in a period ('.'). It can take three values:

  • deny

    This means that the title SHOULD NOT end in a period. This is the default value of the option, as this is the most common policy.

  • allow

    This means that the title MAY end in a period, i.e., it doesn't matter.

  • require

    This means that the title SHOULD end in a period.

title-match [!]REGEXP

This option may be specified more than once. It defines a list of regular expressions that will be matched against the title. If the '!' prefix is used, the title must not match the REGEXPs. Otherwise, the log must match REGEXPs.

This allows you, for example, to require that the title starts with a capital letter:

  [githooks "checklog"]
    title-match = ^[A-Z]

body-max-width INT

This option specifies a limit to the width of the commit log message's body lines, in characters. It's 72 by default. If you set it to 0 the plugin imposes no limit on the body line's width.

Only lines starting with a non-whitespace character are checked against the limit. It's a common style to quote things with indented lines and we like to make those lines free of any restriction in order to keep the quoted text authentic.

match [!]REGEXP

This option may be specified more than once. It defines a list of regular expressions that will be matched against the commit log messages. If the '!' prefix is used, the log must not match the REGEXPs. Otherwise, the log must match REGEXPs.

The REGEXPs are matched with the /m modifier so that the ^ and the $ meta-characters, if used, match the beginning and end of each line in the log, respectively.

This allows you, for example, to disallow hard-tabs in your log messages:

  [githooks "checklog"]
    match = !\\t

spelling BOOL

This option makes the plugin spell check the commit log message using Text::SpellChecker. Any spelling error will cause the commit or push to abort.

Note that Text::SpellChecker isn't required to install Git::Hooks. So, you may see errors when you enable this check. Please, refer to the module's own documentation to see how to install it and its own dependencies (which are Text::Hunspell or Text::Aspell).

spelling-lang CODE

The Text::SpellChecker module uses defaults to infer which language it must use to spell check the message. You can make it use a particular language passing its ISO CODE to this option.

signed-off-by BOOL

This option requires the commit to have at least one Signed-off-by footer.

Despite of the value of this option, the plugin checks and complains if there are duplicate Signed-off-by footers in the commit.

deny-merge-revert BOOL

This Boolean option allows you to deny commits that revert merge commits, since such beasts introduce complications in the repository which you may want to avoid. (To know more about this you should read Linus Torvalds's How to revert a faulty merge.)

The option is false by default, allowing such reverts.

Note that a revert is detected by the fact that Git introduces a standard sentence in the commit's message, like this:

  This reverts commit 3114a008dc474f098babf2e22d444c82c6496c23.

If the committer removes or changes this line during the commit the hook won't be able to detect it.

Note also that the git-revert command, which creates the reverting commits doesn't invoke the commit-msg hook, so that this check can't be performed at commit time. The checking will be performed at push time by a pre-receive or update hook though.

REFERENCES

  • git-commit(1) Manual Page

    This Git manual page has a section called DISCUSSION which discusses some common log message policies.

  • Linus Torvalds GitHub rant

    In this note, Linus says why he dislikes GitHub's pull request interface, mainly because it doesn't allow him to enforce log message formatting policies.

  • MediaWiki Git/Commit message guidelines

    This document defines MediaWiki's project commit log message guidelines.

  • Proper Git Commit Messages and an Elegant Git History

    This is a good discussion about commit log message formatting and the reasons behind them.

  • GIT Commit Good Practice

    This document defines the OpenStack's project commit policies.

  • A Note About Git Commit Messages

    This blog post argues briefly and convincingly for the use of a particular format for Git commit messages.

  • Git Commit Messages: 50/72 Formatting

    This StackOverflow question has a good discussion about the topic.

  • What do you try to leave in your commit messages?

    A blog post from Kohsuke Kawaguchi, Jenkins's author, explaining what information he usually includes in his commit messages and why.

  • How to revert a faulty merge

    This message, from Linus Torvalds's himself, explains why reverting a merge commit is problematic and how to deal with it.

AUTHOR

Gustavo L. de M. Chaves <gnustavo@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2023 by CPQD <www.cpqd.com.br>.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.