NAME
Git::Hooks::CheckCommit - Git::Hooks plugin to enforce commit 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 = CheckCommit
# These users are exempt from all checks
admin = joe molly
# The @mergers group is used below
groups = mergers = larry sally
[githooks "checkcommit"]
# Reject commits if the author or committer name contains any characters
# other then lowercase letters.
name = !^[a-z]+$
# Reject commits if the author or committer email does not belong to the
# @cpqd.com.br domain.
email = @cpqd\.com\.br$
# Enable several integrity checks on the author and committer emails using
# the Email::Valid Perl module.
email-valid = true
# Only users in the @mergers group can push merge commits.
merger = @mergers
# Rejects pushes with more than two commits in a single branch, in order to
# avoid careless pushes.
push-limit = 2
# Reject commits unless they are signed with a GPG key
# and the signature is good (does not need to be trusted).
signature = good
DESCRIPTION
This Git::Hooks plugin hooks itself to the hooks below to enforce commit policies.
pre-commit, pre-applypatch
This hook is invoked before a commit is made to check the author and committer identities.
post-commit, post-applypatch
This hook is invoked after a commit is made to check its signature. Note that the commit is checked after it has been made and any errors must be fixed with a
git-commit --amend
command afterwards.update
This hook is invoked multiple times in the remote repository during
git push
, once per branch being updated, to check if all commits being pushed comply.pre-receive
This hook is invoked once in the remote repository during
git push
, to check if 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 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 all commits being pushed comply.
submit
This hook is invoked when a change is submitted in Gerrit Code Review, to check if 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 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 several aspects of commits, such as those relating to author and committer identities and commit signatures.
To enable this plugin you should add it to the githooks.plugin configuration option:
[githooks]
plugin = CheckCommit
NAME
Git::Hooks::CheckCommit - Git::Hooks plugin to enforce commit policies
CONFIGURATION
The plugin is configured by the following git options under the githooks.checkcommit
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.
name [!]REGEXP
This multi-valued option impose restrictions on the valid author and committer names using regular expressions.
The names must match at least one of the "positive" regular expressions (the ones not prefixed by "!") and they must not match any one of the negative regular expressions (the ones prefixed by "!").
This check is performed by the pre-commit
local hook.
This allows you, for example, to require that author and committer names have at least a first and a last name, separated by spaces:
[githooks "checklog"]
name = .\\s+.
email [!]REGEXP
This multi-valued option impose restrictions on the valid author and committer emails using regular expressions.
The emails must match at least one of the "positive" regular expressions (the ones not prefixed by "!") and they must not match any one of the negative regular expressions (the ones prefixed by "!").
This check is performed by the pre-commit
local hook.
email-valid BOOL
This option uses the Email::Valid module' address
method to validate author and committer email addresses.
These checks are performed by the pre-commit
local hook.
Note that the Email::Valid module isn't required to install Git::Hooks. If it's not found or if there's an error in the construction of the Email::Valid
object the check fails with a suitable message.
The Email::Valid
constructor (new) accepts some parameters. You can pass the Boolean parameters to change their default values by means of the following sub-options. For more information, please consult the Email::Valid documentation.
githooks.checkcommit.email-valid.mxcheck BOOL
Specifies whether addresses should be checked for a valid DNS entry. The default is false.
githooks.checkcommit.email-valid.tldcheck BOOL
Specifies whether addresses should be checked for valid top level domains. The default is false.
githooks.checkcommit.email-valid.fqdn BOOL
Species whether addresses must contain a fully qualified domain name (FQDN). The default is true.
githooks.checkcommit.email-valid.allow_ip BOOL
Specifies whether a "domain literal" is acceptable as the domain part. That means addresses like: rjbs@[1.2.3.4]
. The default is true.
canonical MAILMAP
This option requires the use of canonical names and emails for authors and committers, as configured in a MAILMAP file and checked by the git-check-mailmap
command. Please, read that command's documentation to know how to configure a mailmap file for name and email canonicalization.
This check is only able to detect known non-canonical names and emails that are converted to their canonical forms by the git-check-mailmap
command. This means that if an unknown email is used it won't be considered an error.
Note that the git-check-mailmap
command is available since Git 1.8.4. Older versions of Git don't have it and Git::Hooks will complain accordingly.
Note that you should not have Git configured to use a default mailmap file, either by placing one named .mailmap at the top level of the repository or by setting the configuration options mailmap.file
and mailmap.blob
. That's because if Git is configured to use a mailmap it will convert non-canonical to canonical names and emails before passing them to the hooks. This will invoke git-check-mailmap
using the -c
option to temporarily configure it to use the MAILMAP file.
These checks are performed by the pre-commit
local hook.
signature {nocheck|optional|good|trusted}
This option allows one to check commit signatures according to these values:
nocheck
By default, or if this value is specified, no check is performed. This value is useful to disable checks in a repository when they are enabled globally.
optional
This value does not require commits to be signed but if they are their signatures must be valid (i.e. good or untrusted, but not bad).
good
This value requires that all commits be signed with good signatures.
trusted
This value requires that all commits be signed with good and trusted signatures.
This check is performed by the post-commit
local hook.
merger WHO
This multi-valued option restricts who can push commit merges to the repository. WHO may be specified as a username, a groupname, or a regex, like the githooks.admin
option (see "CONFIGURATION" in Git::Hooks) so that only users matching WHO may push merge commits.
push-limit INT
This limits the number of commits that may be pushed at once on top of any reference. Set it to 1 to force developers to squash their commits before pushing them. Or set it to a low number (such as 3) to deny long chains of commits to be pushed, which are usually made by Git newbies who don't know yet how to amend commits. ;-)
check-code CODESPEC
If the above checks aren't enough you can use this option to define a custom code to check your commits. The code may be specified directly as the option's value or you may specify it indirectly via the filename of a script. If the option's value starts with "file:", the remaining is treated as the script filename, which is executed by a do command. Otherwise, the option's value is executed directly by an eval. Either way, the code must end with the definition of a routine, which will be called once for each commit with the following arguments:
Since the codes may take much time to run, the plugin checks if the githooks.timeout
option has been violated after each code runs.
GIT
The Git repository object used to grok information about the commit.
COMMIT
This is a hash representing a commit, as returned by the Git::Repository::Plugin::GitHooks::get_commits method.
REF
The name of the reference being changed, for the update and the pre-receive hooks. For the pre-commit hook this argument is undef.
The subroutine should return a Boolean value indicating success. Any errors should be produced by invoking the Git::Repository::Plugin::GitHooks::error method.
If the subroutine returns undef it's considered to have succeeded.
If it raises an exception (e.g., by invoking die) it's considered to have failed and a proper message is produced to the user.
REFERENCES
-
Module used to check validity of email addresses.
A Git Horror Story: Repository Integrity With Signed Commits
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.