Useful git pre-commit hooks for R related projects
A collection of git pre-commit hooks to use with pre-commit.com. Currently, we have:
style-files: A hook to style files with styler. Only commit code corresponding to the tidyverse style guide. NOTE: devel version of styler strongly suggested. Install via
remotes::install_github('r-lib/styler'). To customize, see Hooks arguments below.
readme-rmd-rendered: Make sure
README.Rmdhasn’t been edited more recently than
README.md, i.e. remind you to render the
parsable-R: Checks if your
.Rfiles are “valid” R code.
no-browser-statement: Guarantees you that you don’t accidentally commit code with a
browser()statement in it.
spell-check: Checks spelling with
spelling::spell_check_files(). Excluded are R and python scrips as well as .gitignore. To customize, see Hooks arguments below.
roxygenize: A hook to run
roxygen2::roxygenize(). Makes sure you commit your
.Rdchanges with the source changes.
deps-in-desc: Checks if packagese used in the
pkgname::fun()syntax are listed in your DESCRIPTION file.
use-tidy-description: A hook to run
usethis::use_tidy_description()to ensure dependencies are ordered alphabetically and fields are in standard order.
lintr: A hook to run
lintr::lint()to check that R files are lint free.
To add a pre-commit hook to your project, install pre-commit as
described in the official documentation
and make sure the executable
pre-commit is in a place that is on your
If you installed pre-commit, you can add it to a specific project by
.pre-commit-config.yaml file that has a structure like this:
repos: - repo: https://github.com/lorenzwalthert/pre-commit-hooks rev: v0.0.0.9008 hooks: - id: style-files - id: parsable-R - id: no-browser-statement - id: readme-rmd-rendered - id: roxygenize - id: use-tidy-description - id: lintr
repo key points to the place where the source code of the hooks
are stored, not the repo you want to apply them to.
Some hooks also take arguments, see section Arguments below.
If you want to see the file
.pre-commit-config.yaml in RStudio, you
have to enable “Show Hidden Files” in the Files Pane of RStudio under
pre-commit install in your repo and you are done. The next
time you run
git commit, the hooks listed in your
.pre-commit-config.yaml will get executed before the commit. When any
file is changed due to running a hook, the commit will fail. Do not
abort while hooks are running. Non-staged changes are stashed to a
temp directory when the hooks are run and may not easily be recovered
afterwards. You can inspect the changes introduced by the hook and if
satisfied, you can attempt to commit again. If all hooks pass, the
commit is made. You can also temporarily disable
hooks. If you
succeed, it should look like this:
You can also add other hooks from other repos, by extending the
.pre-commit-config.yaml file, e.g. like this:
- repo: https://github.com/pre-commit/pre-commit-hooks rev: v1.2.3 hooks: - id: check-added-large-files
To update the hook revisions, just run
why using hooks?
The goal of pre-commit hooks is to improve the quality of commits. This is achieved by making sure your commits meet some (formal) requirements, e.g:
that they comply to a certain coding style (with the hook
that you commit derivatives such as
.Rdfiles with their source instead of spreading them over multiple commits.
and so on.
As all changes enter a repository history with a commit, we believe many checks should be performed at that point, and not only later on a CI service. For example, creating auto-commits at a CI service for styling code creates unnecessary extra commits, as styling can be checked at the time of committing and is relatively inexpensive.
why using the pre-commit framework?
Implementing hooks in a framework such as
pre-commit.com has multiple benefits compared
to use simple bash scripts in
easily use hooks other people wrote, in bash, R, python and other languages. There is a wealth of useful hooks available, most listed here. For example,
check-added-large-filesprevents you from committing big files, other hooks validate json or yaml files and so on.
No need to worry about dependencies, testing, different versions of hooks, file filtering for specific hooks etc. It’s handled by pre-commit.
Hooks are maintained in one place, and you just need a
.pre-commit-config.yamlfile. No need to c/p hooks from one project to another.
You have an idea for a hook? Please file an issue.
Arguments are specified as described in the pre-commit.com
is, as children in the
.pre-commit-config.yaml. The following hooks
style_funif you want to use another style guide than the default. The below example styles code according to the one-line-style:
args: [--style_pkg=oneliner, --style_fun=one_line_style].
ignore_filestakes a regular expression matched with
base::grep()to ignore further files from the hook. Argument
langis passed to
lintr: Arguments are not supported. Instead,
lintrconfig should be specified in a
.lintrconfig file in Debian Control Field Format as specified in the