diff --git a/docs/howtos/development/setup-pre-commit-hooks.md b/docs/howtos/development/setup-pre-commit-hooks.md index 8d047a4b92bf49fb634b9ca894659bd2647960b7..74d60b74d1753357cf2f1df8a4e00ee59fa151b3 100644 --- a/docs/howtos/development/setup-pre-commit-hooks.md +++ b/docs/howtos/development/setup-pre-commit-hooks.md @@ -8,11 +8,14 @@ We add pre-commit hooks in order to run various linting and auto-formatting tool before they are committed and pushed to GitLab. This how-to guide covers how to add pre-commit hooks to an existing project. -## Standard hooks to add to all projects - !!! info If you are using one of our boilerplates, an appropriate set of hooks will already be present. +Projects should usually have a standard set of pre-commit hooks and some additional +language-specific hooks + +## Standard hooks to add to all projects + Add the following hooks to all projects, by placing them in `.pre-commit-config.yaml` at the root of the project: @@ -54,34 +57,10 @@ repos: [set-up renovatebot](site:explanations/renovatebot) to keep this and your project's other dependencies up-to-date. -## Installing pre-commit hooks - -After adding a `.pre-commit-config.yaml` or modifying it, the following should be run in order to -set-up the hooks: - -```sh -pre-commit install -``` - -## Testing pre-commit hooks +## Python-specific hooks -Normally, pre-commit will run against files which are staged to be committed. To test the -hooks separately from a git commit against all files in your repository, for -instance if to re-format all existing source code to conform to a relevant style guide, -run: - -```sh -pre-commit run --all-files -``` - -## Language-specific hooks - -Additionally, hooks should be added to process the particular source code languages contained in -the project: - -### Python - -The following pre-commit plugins should be added for Python projects (replacing the rev parameters +Additionally, the following pre-commit plugins should be added to `.pre-commit-config.yaml` for +Python projects (replacing the rev parameters with latest releases of the plugins): ```yaml @@ -119,12 +98,12 @@ with latest releases of the plugins): args: [--explicit-package-bases] ``` -### Java +## Java-specific hooks -To ensure your Java source is formatted consistently, use the +Additionally, we use the [google-java-format](https://gitlab.developers.cam.ac.uk/uis/devops/continuous-delivery/precommit-google-java-format) -pre-commit hook by adding the following to your -`.pre-commit-config.yaml` in the root of your project(s): +hook to ensure that Java source is formatted consistently. Add the following to +`pre-commit-config.yaml` for Java projects: ```yaml - repo: https://gitlab.developers.cam.ac.uk/uis/devops/continuous-delivery/precommit-google-java-format @@ -154,20 +133,79 @@ path. If your Java project requires a different version of Java to compile, you can use [sdkman](https://sdkman.io/) to easily switch between different versions at your command line. -#### Configuring Git to ignore bulk formatting commits +## Installing pre-commit hooks -Adding the -[google-java-format](https://gitlab.developers.cam.ac.uk/uis/devops/continuous-delivery/precommit-google-java-format) -pre-commit hook to an existing project can result in formatting a large number of files. If you -use `git blame` to show changes from previous commits, a single commit with a large number of -formatting changes can reduce the usefulness. To avoid this issue, commit a file in the root of -your project called `.git-blame-ignore-revs` (or similar) and add to it a list of the commit -SHAs to ignore. To configure git to ignore these commits, use: +After adding a `.pre-commit-config.yaml` or modifying it, the following should be run in order to +set-up the hooks: ```sh +pre-commit-install +``` + +The above command will also need to be run after the repository has been newly-cloned in order to +set-up the hooks on your local copy. + +## Using pre-commit + +Having been set-up, pre-commit will run against staged files whenever you run `git commit` in this +repository. If files do not conform to the checks, then where possible the pre-commit hooks will +modify them accordingly. The commit will be aborted. + +The modified files can then be re-staged with `git add` and the commit re-tried. + +## Resolving existing compliance failures + +The behaviour above will likely not be sufficient when adding pre-commit to an existing project. +For example: + +- you may desire to re-format all existing source code to conform to a relevant style guide +- when a repository is using our +[standard CI templates](https://gitlab.developers.cam.ac.uk/uis/devops/continuous-delivery/ci-templates/), +the CI pipeline `pre-commit` job executes the checks against _all_ files in the repository. This +will cause the pipeline to fail if there is any existing code which does not conform to the +pre-commit checks. + +You can execute the hooks separately from a git commit against all files in your repository by running: + +```sh +pre-commit run --all-files +``` + +## Configuring Git to ignore bulk formatting commits¶ + +Adding pre-commit hooks to an existing project can result in formatting a large number of files. If +you use git blame to show changes from previous commits, a single commit with a large number of +formatting changes can reduce the usefulness. + +This will often produce a large set of formatting changes which do not affect the behaviour or +design of the code. Once committed, these would limit the usefulness of `git blame`, since many +lines of code would be caught up in this bulk-formatting-change commit. + +To avoid this, having applied the commit its SHA can be added to a `.git-blame-ignore-revs` file in +the root of the repository. For example: + +```bash +# initial pre-commit formatting changes +c998bb1ed4b3285398c9c7797135d3f060243c6a +``` + +You can then configure _your local copy_ of the repository by running: + +```bash git config blame.ignoreRevsFile .git-blame-ignore-revs ``` +and commit the file for the benefit of your colleagues: + +```bash +git add .git-blame-ignore-revs +git commit -m "chore: add .git-blame-ignore-revs" +``` + +It should be noted that `git config` changes do not get pushed or persisted, so these commits will +still show in the `blame` view on GitLab and for other users unless/until they set +`blame.ignoreRevsFile` in their local copy of the repository. + ## Summary In this how-to you learned how to set-up a standard set of pre-commit hooks on a project.