What happened
Ten consumer trees carry hand-written
.githooks/{pre-commit,commit-msg,pre-merge-commit,pre-push} delegates
that predate hooks --install. uphold hooks --install --adopt (1.19.0)
refused all ten with exit 2. Three of the four files in each tree spell
the hook directory inline, on the exec line:
exec prek hook-impl --hook-dir "$(cd "$(dirname "$0")" && pwd)" ...
where delegate_hook in src/hooks.rs binds it first:
hook_dir="$(cd "$(dirname "$0")" && pwd)"
exec prek hook-impl --hook-dir "$hook_dir" ...
--check reported the pre-push copy as adoptable and the other three as
"NOT the text this binary writes". The consumers git rm-ed the four
files and ran plain --install, which is the move-aside #199 asked
--adopt to spare them.
Why
install in src/hooks.rs walks STAGES in order and, under
Mode::Adopt, compares effective_lines(¤t) with
effective_lines(&body) per file. effective_lines drops comments,
joins continuations and collapses whitespace, so a different wrap is one
spelling, but an inlined $(...) argument and the same expression bound
to hook_dir a line earlier are two lines against three, and the first
mismatch is return Err(...). One differing file refuses the directory,
and a file adopted in an earlier iteration has already been rewritten
with its marker when the loop stops: pre-commit matching and commit-msg
not leaves one marked file, exit 2, and nothing else done.
What would close it
Adopt per file: take over the copies whose lines match, refuse only the
ones that do not, name them, and write nothing until every file has been
judged. Compare a normalised form that reads an inlined $(...)
argument and the same expression assigned to a variable on the preceding
line as one spelling -- or, simpler, compare the argv the exec line would
produce after substituting the local assignments above it. A test with
the three-line and two-line forms of one delegate, adopted as equal.
What happened
Ten consumer trees carry hand-written
.githooks/{pre-commit,commit-msg,pre-merge-commit,pre-push}delegatesthat predate
hooks --install.uphold hooks --install --adopt(1.19.0)refused all ten with exit 2. Three of the four files in each tree spell
the hook directory inline, on the exec line:
where
delegate_hookinsrc/hooks.rsbinds it first:--checkreported the pre-push copy as adoptable and the other three as"NOT the text this binary writes". The consumers
git rm-ed the fourfiles and ran plain
--install, which is the move-aside #199 asked--adoptto spare them.Why
installinsrc/hooks.rswalksSTAGESin order and, underMode::Adopt, compareseffective_lines(¤t)witheffective_lines(&body)per file.effective_linesdrops comments,joins continuations and collapses whitespace, so a different wrap is one
spelling, but an inlined
$(...)argument and the same expression boundto
hook_dira line earlier are two lines against three, and the firstmismatch is
return Err(...). One differing file refuses the directory,and a file adopted in an earlier iteration has already been rewritten
with its marker when the loop stops: pre-commit matching and commit-msg
not leaves one marked file, exit 2, and nothing else done.
What would close it
Adopt per file: take over the copies whose lines match, refuse only the
ones that do not, name them, and write nothing until every file has been
judged. Compare a normalised form that reads an inlined
$(...)argument and the same expression assigned to a variable on the preceding
line as one spelling -- or, simpler, compare the argv the exec line would
produce after substituting the local assignments above it. A test with
the three-line and two-line forms of one delegate, adopted as equal.