How does it work? What’s the magic?

No magic. Git provides a mechanism for pre-commit hooks. Since it’s cumbersome to copy bash scripts and keep them updated in some hidden .git/ directory, people wrote frameworks to basically maintain these files. One of them is pre-commit.com. So you call git to commit, git calls its internal hooks, these hooks (bash scripts in the simplest case) are provided by the pre-commit framework. And where does pre-commit get all it’s nice hooks from? From us.

How are hooks accessed? What happens if there’s no internet connection?

Internet connection is required during installation (precommit::install_precommit()) and project initialization (precommit::use_precommit()) as well as when hooks are updated (precommit::autoupdate()). Otherwise, no internet connection is required. Hooks will be placed into .git/ during calling the precommit::use_precommit() and afterwards you can precommit::autoupdate() to replace the hooks with their new version (that’s what I think happens).

Can you use it outside RStudio?

Yes, all but the open_config() and open_wordlist() to open files in RStudio.

Can I use the hooks provided in this package without installing the R package?

Yes, apart from the roxygenize hook (which uses an exported function from {precommit}). The hooks work even if you don’t have the R package installed because all you need to have for the hooks to work is the pre-commit executable. It will git clone the hooks from this repo into .git/hooks or similar. All exported functions of this package are just for the users convenience.

How can I make sure that my contributors are using the hooks?

They must follow the installation instructions in the README, i.e. run

remotes::install_github("lorenzwalthert/precommit")
precommit::install_precommit()
precommit::use_precommit()

The last call can be omitted by users who have automatically enabled pre-commit hooks.

To enforce all hooks pass, you can follow the advice on how to use pre-commit in a CI/CD setup.

What if not all people who are committing to this repo want to use the hooks?

This is not a problem, git will only run the hooks in a local repo after precommit::use_precommit() has been run successfully from within this local repo on your machine. You can also uninstall anytime with precommit::uninstall_precommit(). Anyone who does not want to use the hooks simply should not run precommit::use_precommit(). You can also temporarily disable hooks as described here.

How does one create a new pre-commit hook?

How to contribute new hooks is explained in CONTRIBUTING.md.

Why are my hooks running slowly?

Some of the hooks depend on R functions that run slowly, e.g. the style-files hook depends on styler, which is not very fast. Also, note that for each hook, R is started. Make sure your startup process is quick for non-interactive use, e.g. your .Rprofile and related files do not have a long execution time when pre-commit calls them. You can wrap code in if (interactive()) to only execute it in an interactive session or wrap it in if (Sys.getenv("PRE_COMMIT") != "1") (if you have pre-commit >= 2.5.0), so it won’t run when pre-commit hooks are ran. Find out more about the startup process with ?startup.


There is more. Check out the documentation of the pre-commit framework.