Installs and removes the git hooks that run mix presubmit.
Two hooks work together so that the change set checked is the commit that is about to exist:
prepare-commit-msglearns from git whether the commit amendsHEAD(sourcecommitwithHEAD's SHA) and recordsHEAD^as the base in.git/presubmit_base, or removes that file otherwise.commit-msgrunsmix presubmit --staged --message-file "$1", adding--base <recorded>when amending, so rules seeHEAD^ → index— the amended commit — rather than the delta sinceHEAD, which could never satisfy a rule whose other half lives in the original commit.
Git reports the message source as message rather than commit when
--amend is combined with -m or -F, so that form of amend is not
detected and the delta since HEAD is what gets checked; amend with the
editor or --no-edit, or run mix presubmit --staged --base HEAD^.
A hook blocks the commit only on presubmit's verdict. It points
PRESUBMIT_VERDICT at a file under the git directory, and mix presubmit
writes pass or fail there once its rules have run (Presubmit.CLI). When
there is no verdict, presubmit did not run: Mix stopped first (stale or
unresolvable dependencies, a project that does not load), or presubmit hit a
configuration error or crashed. That is a fault in the checkout or the tool,
not in the commit, so the hook prints presubmit could not run: <the error>; commit allowed, CI still checks and lets the commit through. Presubmit 0.1.0
writes no verdict; its report (a line starting Examining) shows that it
ran, and then its exit status is the verdict.
The hooks also step aside, with a note, while a merge is in progress or
when amending a merge commit (the change set would be someone else's
branch), and when mix is not on PATH (GUI clients often lack the
developer's shell environment). A rule that crashes is reported but does not
block the commit (--on-error warn). CI remains the backstop for all of
these.
Hooks are installed for the project in the current directory; in a
subdirectory project of a larger repository the scripts cd there first.
A hook that was not installed by this module is never overwritten, and
installation is refused when core.hooksPath points hooks elsewhere.
Summary
Functions
The hooks installed by default: prepare-commit-msg and commit-msg.
The hooks this module knows how to install.
Installs the named hooks for the project at project_dir (the directory
containing mix.exs), into its repository's hooks directory.
Which of the known hooks are currently installed by this module.
The script installed for hook, for a project at project_rel relative
to the repository root ("." for a root project).
Removes every hook this module installed. Foreign hooks are left alone.
Types
@type hook() :: String.t()
Functions
@spec default() :: [hook()]
The hooks installed by default: prepare-commit-msg and commit-msg.
@spec hooks() :: [hook()]
The hooks this module knows how to install.
Installs the named hooks for the project at project_dir (the directory
containing mix.exs), into its repository's hooks directory.
Returns the paths written, or {:error, message} when core.hooksPath
redirects hooks or a target is a hook that was not installed by this module.
Which of the known hooks are currently installed by this module.
The script installed for hook, for a project at project_rel relative
to the repository root ("." for a root project).
Removes every hook this module installed. Foreign hooks are left alone.