fix(redact-prepush): preserve the trailing newline handed to chained pre-push.local

The chaining wrapper captured stdin with $(cat), which strips the trailing
newline — a chained shell hook built on `while read` then never entered its
loop for the final (usually only) ref line and exited 0, failing OPEN. Use
the printf-x sentinel so the byte-exact input reaches the chained hook, with
tests covering both the pass-through and the short-circuit paths.

Contributed by @francis-eye (PR #2358).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-14 20:20:49 -07:00
co-authored by Claude Fable 5
parent d77a2c8e58
commit 57a211e4b0
2 changed files with 54 additions and 1 deletions
+6 -1
View File
@@ -73,10 +73,15 @@ function installPrepushHook(): void {
}
// stdin is single-consume: capture it once, feed both the chained hook and ours.
// The `printf x` sentinel preserves the trailing newline that `$(cat)` strips.
// Without it, a chained shell pre-push.local built on `while read` silently
// drops the final (often only) ref line and exits 0 — the guard reports
// success having scanned nothing, i.e. it fails OPEN.
const wrapper = `#!/usr/bin/env bash
${MANAGED_MARKER}
set -euo pipefail
_input="$(cat)"
_input="$(cat; printf x)"
_input="\${_input%x}"
_local="$(git rev-parse --git-path hooks/pre-push.local)"
if [ -x "$_local" ]; then
printf '%s' "$_input" | "$_local" "$@" || exit $?