pre-commit is a framework that uses Git hooks to go through checklists before the commit. This precheck can help to review if your code is meeting the coding standards or if the commiting file is too large. And the commit will only be made when all pre-defined conditions are met. So that one can worry less on the atting and focus more on building the code.
What is Git Hooks?
Git hooks are the s triggered by Git when certain actions take place, such as commit and merge. They contain customised actions to be executed before or after when certian Git actions are used.
There are 2 ways the hooks can be implemented; Client-side and Server-side.
Client-side hooks are called locally by actions such as commit, whereas, server-side hooks are called on the server when receiving a push.
This framework helps to build the client-side hooks to trigger before the commit.
How to Set Up
pre-commit, the following steps are required.
The framework can be installed with the following lines.
$ pip install pre-commit
$ brew install pre-commit
$ conda install -c conda-forge pre-commit
pre-commit, configuration needs to be defined with the sources of the
They are defined in the configuration file,
.pre-commit-config.yaml in the target repository, and follows the at below. Although, the at is written for Python,
pre-commit works for any programming language.
repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.1.0 hooks: - id: trailing-whitespace - repo: https://github.com/psf/black rev: 22.1.0 hooks: - id: black args: [--config=pyproject.toml] - repo: https://github.com/PyCQA/flake8 rev: 4.0.1 hooks: - id: flake8 args: [--config=.flake8] - repo: https://github.com/asottile/reorder_python_imports rev: v2.7.1 hooks: - id: reorder-python-imports args: [--py37-plus, --add-import, 'from __future__ import annotations'] exclude: ^testing/resources/python3_hooks_repo/
|repo||repository url to git clone from|
|rev||repository revision/release tag|
|hooks||hooks to implement from the repository|
|id||identification for the hooks|
|args||list of eters to pass to the hooks|
|exclude||file exclusion pattern|
In the example, the following hooks are configured:
pre-commithook to remove trailing whitespaces
black: Python atter
- code : https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html
- Key differences to PEP 8 includes:
- 88 characters for a line instead of 79 characters
- Use of double quotes instead of single quotes
flake8: PEP 8 compliance checker
- reorder_python_imports: reordering tool for Python imports
- Note that
flake8hooks contain configuration arguments which will be discussed next
Compatibility between Black & Flake8
In the example,
black is used to at the code , followed by 'flake8' to further comply with PEP 8 standards for non-style linting concerns.
black is compliant with PEP 8, there are some opiniated atting that may clash with
Hence, it is important to amend the configuration to prevent spewing errors.
black repository, the following configuration can be set for
flake8 to avoid lison by creating a configuration file,
.flake8 file in the target repository. (source: https://github.com/psf/black/blob/main/.flake8)
[flake8] ignore = E203, E266, E501, W503 # line length is intentionally set to 80 here because black uses Bugbear # See https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#line-length for more details max-line-length = 80 max-complexity = 18 select = B,C,E,F,W,T4,B9
In addition, a configuration file,
pyproject.toml can also be set for
black to ensure it ignores certain files and the string quote normalisation (converting " to ') is disabled.
The string quote normalisation is upto personal preference.
[tool.black] line-length = 88 skip-string-normalization = 1 include = '\.pyi?$' exclude = ''' /( \.git | \.hg | \.mypy_cache | \.tox | \.venv | _build | buck-out | build | dist )/ '''
After the configuration is done,
pre-commit needs to be installed into the git hooks of the target repository. Ensure all relelvant configuration files are in the same target repository ectory.
$ pre-commit install
This command will enable
pre-commit to be triggered before the commit for the target repository.
To manually execute the hooks, the follow commands can be used. When
pre-commit runs, it will download, install and run the hooks specified in the
$ pre-commit run --all-files $ pre-commit run <hook_id> # for specific hooks
When configured hooks are not installed, they are installed first.
Hooks are triggered to check the codes.
Once the code has passed all the hooks, then the code gets committed (or is ready to be committed if hooks called manually).
Hooks can be bypassed by adding the
--no-verify option to commit command.
$ git commit --no-verify -m "comment"
Environment and Cache
pre-commit stores its hook environment and cache at
The path can be altered by setting the following environment variables.
pre-commituses this variable's path
pre-commituses this variable's path followed by
If the repository is located in the network drive using UNC (Universal Naming Convention), Git may not recognise the path and
pre-commit may not be installed properly.