Git hooks and pre-commit¶
In this section you will:
Learn about git hooks
Configure pre-commit, a handy program to set up your git hooks.
What are git hooks for?¶
Git hooks are way of running custom scripts on your repository either client-side or server-side. In fact, server-side hooks can be used to trigger things like continuous integration. Here we will focus on some client-side (i.e. on your local machine) hooks that will ensure certain formatting standards are met prior to commits. This way, all of your commits are meaningful changes to code, and your git history doesn’t get littered with “apply black” and “fix PEP-8” messages. Notably these kinds of tests can also be run during continuous integration (as seen in the configuration of Travis-CI).
We also include a hook that scrubs any output from jupyter notebooks. This way, the only time git thinks a notebook has changed is when the contents of the cells have changed.
It’s just formatting, who cares?¶
Ideally, someone else is going to read your code, and better yet, make changes to it. Having a consistent code style and format makes that easier. Going a step further, using an even more specific formatter such as Black, ensures that changes to programs produce the smallest changes to text possible.
Configuring pre-commit¶
The cookiecutter template has already generated a configuration file for pre-commit, which will construct your git hooks.
repos:
- repo: https://github.com/ambv/black
rev: stable
hooks:
- id: black
language_version: python3.7
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.0.0
hooks:
- id: flake8
- repo: https://github.com/kynan/nbstripout
rev: 0.3.9
hooks:
- id: nbstripout
You can customize this to your liking, or not use it entirely.
For example, if you are migrating a large amount of existing code that is not compliant with
PEP8, yet managing notebooks collaboratively,
you may want to remove the section that does flake8
style-checking and black
.
Running pre-commit install
inside the top-level directory of your repository
will use this configuration file to set up git hooks to run prior to completing a commit.
Committing Changes¶
Assuming you’ve decided to keep nbstripout
, black
, and flake8
as hooks, each
time you commit changes to the repository files will be checked for these standards.
If your files don’t fit the standard, the commit will fail.
For example with notebooks and nbstripout
:
Before you commit changes to git the output area of the notebooks must
be cleared. This ensures that (1) the potentially-large output artifacts
(such as figures) do not bloat the repository and (2) users visiting the
tutorial will see a clean notebook, uncluttered by any previous code
execution. This can be accomplished by running nbstripout
before the commit.
If you forget to do this, an error message will protect you from accidentally committing. It looks like this:
$ git add .
$ git commit -m "oops"
nbstripout...............................................................Failed
- hook id: nbstripout
- files were modified by this hook
What happened here? Your attempt to commit has been blocked. The files have been fixed for you—clearing the outputs from your notebooks, but git-hooks won’t assume you want these fixes committed. Before trying again to commit, you must add those fixes to the “staged” changes:
# Stage again to include the fixes that we just applied (the cleared output areas).
$ git add .
# Now try committing again.
$ git commit -m "this will work"
nbstripout...............................................................Passed
[main 315536e] changed things
2 files changed, 44 insertions(+), 18 deletions(-)
The same procedure holds for applying black to files. However, Flake8 is a checker and not a formatter. It will only report issues, not change them.