15

Some hooks can take a while to run, and I would like to run those before I push, but not before each particular commit (for example, pylint can be a bit slow).

I've seen the following:

But it's still not clear to be how I'm supposed to set this up.

Here is what I have tried:

default_stages: [commit]
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v3.1.0
    hooks:
      - id: end-of-file-fixer
      - id: trailing-whitespace
  - repo: https://github.com/psf/black
    rev: 19.10b0
    hooks:
      - id: black
        stages: [push]

From that I'm expecting the first couple of hooks to run before a commit (which they do), but I'm expecting black to run before pushing, which it doesn't.

To test that I have created the following file:

"""This is a docstring."""

print('this should be formatted')

Which is certainly not being formatted by black.

anthony sottile
  • 61,815
  • 15
  • 148
  • 207
baxx
  • 3,956
  • 6
  • 37
  • 75

1 Answers1

24

your configuration is correct, except that the whitespace hooks in pre-commit/pre-commit-hooks set stages themselves so they won't be affected by default_stages

adjusting your configuration slightly:

repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v3.1.0
    hooks:
      - id: end-of-file-fixer
        stages: [commit]
      - id: trailing-whitespace
        stages: [commit]
  - repo: https://github.com/psf/black
    rev: 19.10b0
    hooks:
      - id: black
        stages: [push]

next you'll need to make sure both of the hook scripts are installed

You can install both the pre-commit and pre-push commit at the same time using:

pre-commit install --hook-type pre-commit --hook-type pre-push

or you can run them separately:

pre-commit install  # installs .git/hooks/pre-commit
pre-commit install --hook-type pre-push  # installs .git/hooks/pre-push

note that the second command comes directly from the documentation on using pre-push


disclaimer: I'm the author of pre-commit and pre-commit-hooks

anthony sottile
  • 61,815
  • 15
  • 148
  • 207
  • Thanks @anthony, this works : ). However, if `default_stages` applies to all stages, why is it necessary to specify `--hook-type` for these 2 stages? I had this very same problem and my expectation, after reading the doc, was that by not specifying any stages globally, pre-commit would install the hooks configured at the specified stages. Why isn't this so? – Julian B. Mar 04 '22 at 12:49
  • @JulianB. `default_stages` is only the fallback value for `stages` when unspecified, it does not "applies to all stages" -- it's entirely unrelated to `--hook-type`. some hooks specify `stages` that's more broad than the hooks you're actually using so taking that at face value for `install` would be incorrect. also pre-commit would need to clone / install repos to even get that info (which is intentionally not part of `install` unless `--install-hooks`) so it's technically infeasible. there's a bunch of dupes in the issue tracker you can search there – anthony sottile Mar 04 '22 at 13:53