Easily configurable git hooks templates without bullshit
The reason of this project, is that some Git Hooks usually have no interest in being checked out AFTER a push (like with github actions). Checking the format, preventing the commit of certain information or files, etc. All this stuff should be checked locally to prevent mistake and leave no trace of it in the history.
This type of tool already exists, but it's extremely heavy and has many dependencies (like with npm, python, etc.). This is not the case here, it's just bash script that uses the default tools of a Unix like system and to be easily configurable with the git config command.
- To finish Features implementations
- A gitlab job to run unit test
- To testing supported systems
- A Documentation review
- Gnu/Linux
- Windows
- macOS (not tested)
- BSD (need to validate posix compatibility)
- Can be configured with
git config
globally or locally see configuration - Colored Error and Success message output
- Unit testing for each hook
- emoji type support for commit message
- Check and Auto-fix commit message format
- Check and Auto signoff when missing if required
- Check and Auto pgp singing when missing if required
- Avoid duplicate commits message
- Avoid to commit binary files with auto or interactive fix
- Avoid to commit large files with auto or interactive fix
- Support of DNCT (Do Not Commit This) tags in files
- Prevent the commit of the mac ds_store ...
- Prevent pushing to remote branches that is not up-to-date with local branches
- Prevent pushing commit with WIP tag
- Prevent commit when previous commit is a WIP
- Require a .gitignore file to be present in the root of the repository
- Emit a warning if potential sensitive information is found in a file
- Branch naming convention
- Branch protection rules
- Enforce --force-with-lease instead of --force
These scripts are automatically used by Git according to the actions taken,
like every githooks
and comforming to the githooks manual page.
You can disable MOGH hooks for a specific project with the dedicated option. Like this:
git config mogh.enabled 0
Or you can skip it one time with the git --no-verify
flag for push actions.
To work properly, these scripts don't require any exta dumb tools like npm, python or other crap. Requirements are probably by default on your system.
git
of course ...printf
to format a stringbash
this is an sh-compatible shellgrep
searching plain-text data sets for linesfile
checking file typestat
checking file sizesed
parses and transforms texttr
operation of replacing or removing specific characterspgp
if you require a PGP signaturejq
(only for unit testing) JSON processor
To install it, just run the following command:
curl -sL https://gitlab.com/adrienK/mogh/-/raw/main/tools/install.sh | bash
That will clone the repository to your git templates directory and
enable it to the global git hooks.
This is not a destructive operation, if you already have a git hook installed
it will not be overwritten but moved to hooks.old
.
Or you can install it manually by running something like this:
mkdir -p ~/.git/templates
git clone https://gitlab.com/adrienK/mogh.git ~/.git/templates/hooks
git config --global init.templatedir ~/.git/templates
To update it, just run the following command:
curl -sL https://gitlab.com/adrienK/mogh/-/raw/main/tools/update.sh | bash
That will globally made an git pull
to the repository to update the templates.
If the repository is not cloned yet, it returns an error.
To update hooks in a repository, run the following command on it:
git init
According to the documentation, this can update repository.
Create an empty Git repository OR reinitialize an existing one
To update it, run the following command:
WARNING: There use an rm -rf
, check the path if you're not sure !
templatedir="$(git config init.templatedir)" // find the install folder
rm -rf "$templatedir" // remove it
Every local git repos keep their git hooks. Git init make a copy of hooks, not a link. So you have two choices :
- Removing manually
.git/hooks
for every local repos - Disable MOGH to prevent any execution
git config --global mogh.enabled 0
The configuration use the default git config file, so you can change it with
the git command git config
. By default, the configuration is applied only to
the current git repository, but you can apply it globally with the --global
flag option. For more information, see the
documentation.
Local configuration overrides global configuration, except for lists, like
mogh.types.extra
and mogh.types.extra-emoji
. There use "all values for a
multi-valued key" from both configurations like an union of the two lists.
This is a config example, to full config see the next section
# add extra type support to global config
git config --global mogh.types.extra "poop"
git config --global mogh.types.extra "mock"
git config --global mogh.types.extra "break"
# add extra emoji support to global config
git config --global mogh.types.extra-emoji "π©"
git config --global mogh.types.extra-emoji "π€‘"
git config --global mogh.types.extra-emoji "π₯"
# enable the type replacement to emoji
# but only to the current repository
git config mogh.types.emoji 1
Take your git config
and fill it to your needs π
This is the git config
representation of how the default MOGH configuration applied for hooks.
[mogh]
enabled = 1
gitignore = 1
[mogh "dnct"]
enabled = 1
regex = \\[DNCT\\]|DONOTCOMMITTHIS|DO-NOT-COMMIT-THIS|DO_NOT_COMMIT_THIS|DO NOT COMMIT THIS
[mogh "files"]
size-max = 1024
uncache-oversize = 2
uncache-dsstore = 1
uncache-binary = 2
[mogh "gpg"]
required = 1
autofix = 1
[mogh "header"]
autofix = 1
max-length = 80
[mogh "types"]
emoji = 2
[mogh "signoff"]
required = 1
autofix = 1
[mogh "wip"]
prevent-push = 1
secure-commit = 1
[mogh "branch"]
protected = 0
protected-push = 0
protected-name = "main|master"
To enable or disable MOGH hooks.
Can be set to 0 or 1. Default is 1.
To enable or disable the gitignore requirement.
Can be set to 0 or 1. Default is 1.
To enable or disable the dnct tag checker. This tag DO NOT COMMIT THIS is used to prevent the commit of sensitive data.
Can be set to 0 or 1. Default is 1.
To set the dnct tag regex. This is the regex to match the dnct tag.
Default is
\[DNCT\]|DONOTCOMMITTHIS|DO-NOT-COMMIT-THIS|DO_NOT_COMMIT_THIS|DO NOT COMMIT THIS
To enable or disable the ds_store remover. When you work with mac guys ...
Can be set to 0 or 1. Default is 1.
To enable or disable the binary file remover. This flag is used to prevent the commit of executable binaries.
Can be set to 0, 1, 2. Default is 2.
0: keep it; 1: remove from commit; 2: interactive fix.
To set the maximum file size to be committed. This flag is used to prevent the commit of large files.
Can be set to a KB value. Default is 1024.
To enable or disable the file size autofix.
Can be set to 0, 1, 2. Default is 2.
0: keep it; 1: remove from commit; 2: interactive fix.
To enable or disable GPG signing requirement.
This flag will force user to use git -S, --gpg-sign
Can be set to 0 or 1. Default is 1.
To enable or disable automatic GPG signature fixing.
This flag will try to automatically apply the gpg signature to the commit.
Can be set to 0 or 1. Default is 1.
To enable or disable automatic header fixing.
This flag will try to automatically fix the header of the commit.
According to the conventionalcommits.org v1.
Can be set to 0 or 1. Default is 1.
To set the maximum length of the commit header. This flag is used to prevent the commit of too long header.
Can be set to a number. Default is 80.
To add extra commit type to the list of supported types.
By default, all commit type from conventionalcommits.org v1 are available.
Default is an empty list.
Can be added withgit config --global mogh.types.extra "poop"
To enable or disable the emoji type support.
The idea is to use the emoji type instead of the type name.
This is largely inspired by gitmoji.dev.
Can be set to 0, 1, 2. Default is 2.
0: disable; 1: enable; 2: enable but keep the type name.
To add extra emoji commit type to the list of supported types.
In case you have added extra commit type to the list and whant corresponding
emoji, you need to add them here. Warning, the position id in the array is
used to map the commit type to emoji, so you need to keep the same order.
Default is an empty list.
Can be added withgit config --global mogh.types.extra-emoji "π©"
To enable or disable the signoff requirement.
This flag will force user to use git -s, --signoff
Can be set to 0 or 1. Default is 1.
To enable or disable automatic signoff fixing.
This flag will try to automatically add the signoff to the commit.
It use git variable GIT_AUTHOR_NAME
and GIT_AUTHOR_EMAIL
to generate it.
Can be set to 0 or 1. Default is 1.
To enable or disable the WIP tag push prevention.
This flag will prevent the push of a commit with the WIP tag.
Can be set to 0 or 1. Default is 1.
To enable or disable the prevention of commit when previous commit is a WIP.
This flag is to keep the history clean of WIP commits.
Can be set to 0 or 1. Default is 1.
To enable or disable the branch protection.
This flag will prevent the commit on a protected branch.
Particularly useful when your distante repository not support branch protection.
Can be set to 0 or 1. Default is 0.
To enable or disable the branch protection push.
This usefull to prevent allowing or not independently of commiting on a protected branch.
Can be set to 0 or 1. Default is 0.
Note: By default, this flag is set to the value ofmogh.branch.protected
.
To define a regex to match with the branches you wish to protect.
Example: release\/[0-9]+\.[0-9]+
will protect all branches like release/1.0
, release/2.0
, etc.
Default is
main|master
.
For contribute to this project, follow these steps:
- Fork this repository.
- Clone it to your local machine.
- Remove the
.git/hooks
directory of the cloned repositoryrm -rf .git/hooks
. - Create a symbolic link to THIS clone
ln -s "$(pwd)" "$(pwd)/.git/hooks"
. - Create a new branch with the feature, fix... name like
git checkout -b feature/feature-name
. - Commit, push and create a pull request ! π
If you have any questions, feel free to ask. And do not forget to sign your commits.
Every hook has its own unit test (if not, I have missed it).
If you need to write a test. These are located in the tests
directory and have the same name as the hook with the .test
extension, you need to make it executable with chmod +x tests/commit-msg.test
and cases are defined in json format.
To run them, you need to have jq
installed. Then you can run it like every other bash script. Like:
./tests/commit-msg.test
This project is licensed under the GPL 3.0 License - see the LICENSE file for details.