--- /dev/null
+#!/usr/bin/env bash
+
+# Copy me to .git/hooks/pre-commit
+
+set -euo pipefail
+
+if [[ "${GIT_REFLOG_ACTION:-}" == 'rebase (reword)' ]];then
+ exit 0
+fi
+
+tmpdir=
+cleanup_tmpdir() {
+ if [[ "$tmpdir" && -e "$tmpdir" ]];then
+ rm -rf "$tmpdir"
+ fi
+}
+trap cleanup_tmpdir EXIT
+
+# Check out the git index (what's about to be committed) in a temporary
+# directory & run the supplied command there.
+in_git_index_in_tmpdir() {
+ tmpdir=$(mktemp -d)
+ [[ "$tmpdir" && -d "$tmpdir" ]]
+ start_index=$(sha256sum "${GIT_INDEX_FILE:-.git/index}")
+ git checkout-index --prefix="$tmpdir/" -a
+ pushd "$tmpdir"
+ "$@"
+ popd
+ end_index=$(sha256sum "${GIT_INDEX_FILE:-.git/index}")
+ if [[ "$start_index" != "$end_index" ]];then
+ echo "Index changed while pre-commit tests were running. Aborting!"
+ exit 1
+ fi
+}
+
+verify() {
+ cargo test --frozen
+ cargo clippy --frozen -- -D warnings \
+ -W clippy::pedantic \
+ -W clippy::clone_on_ref_ptr \
+ -W clippy::if_then_some_else_none \
+ -W clippy::impl_trait_in_params \
+ -W clippy::pattern_type_mismatch \
+ -W clippy::shadow_reuse \
+ -W clippy::shadow_unrelated \
+ -W clippy::str_to_string \
+ -W clippy::try_err \
+ -A clippy::missing_errors_doc
+ find . -name target -prune -o -name '*.rs' -exec rustfmt --check -- {} +
+}
+
+in_git_index_in_tmpdir verify