fix(lefthook): remove duplicate git-lfs pre-push command
Lefthook v2 runs `git lfs pre-push` internally for pre-push hooks (per docs/usage/features/git-lfs.md; confirmed in internal/run/controller/ lfs.go where the internal handler invokes `git lfs pre-push <remote> <url>` with a buffered `cachedStdin`). Our manual `git-lfs:` command in lefthook.yml was a second invocation against the same remote; the duplicate is directly visible in `LEFTHOOK_VERBOSE=1` output as `[git-lfs] executing hook` (internal) followed by `[lefthook] run: git lfs pre-push` (manual). The previous fix attempt (piped: true, commit1b06804) was based on a wrong understanding of `piped`'s semantics — `piped` controls fail-fast behavior, not stdin routing or sequencing. Default lefthook behavior is already sequential per docs/configuration/parallel.md. That "fix" was placebo; incident 2 (F2 push, zero LFS objects, commit99eedb6) proved it. Phase A investigation: documentary + source confirmation that lefthook owns the LFS pre-push call. Phase B sandbox test against a filesystem remote confirmed the duplicate execution in logs but did NOT reproduce the production hang — likely because the duplicate manual call against a local remote has no LFS server to interact with. A network-y remote (Gitea over SSH/HTTPS) appears to be part of the trigger. Two mechanisms remain plausible (H1: PTY-stdin without EOF in `while read` loop per docs/configuration/use_stdin.md; H4: server-side LFS interaction on the duplicate call). Both are eliminated by the same fix: remove the manual command. LFS uploads continue to work via lefthook's internal handler (verified in sandbox post-fix). Regression coverage: scripts/test-lefthook-pre-push.sh asserts exactly one internal LFS invocation, zero manual ones, and `Uploading LFS objects: 100%` present, against a disposable sandbox. See dev-docs/ADR-LEFTHOOK-LFS-INTEGRATION.md for full context, both misconceptions to prevent regression, and the alternative-scenarios playbook if Phase E ever regresses. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
16
lefthook.yml
16
lefthook.yml
@@ -17,10 +17,11 @@ post-commit:
|
||||
run: bash .githooks/post-commit
|
||||
|
||||
pre-push:
|
||||
# piped: true forces serial execution. Both sync-check and git-lfs
|
||||
# read from stdin (git pipes the push refspec to pre-push hooks);
|
||||
# default parallel execution deadlocks with two stdin readers.
|
||||
piped: true
|
||||
# LFS is handled by lefthook's built-in pre-push LFS hook (see
|
||||
# docs/usage/features/git-lfs.md). Do NOT add a manual `git lfs
|
||||
# pre-push` command here — it duplicates the internal call and
|
||||
# historically caused the pre-push to hang. Background and
|
||||
# mechanism: dev-docs/ADR-LEFTHOOK-LFS-INTEGRATION.md.
|
||||
commands:
|
||||
sync-check:
|
||||
run: bash .githooks/pre-push
|
||||
@@ -33,10 +34,3 @@ pre-push:
|
||||
# behaviour. (Pushing with zero new commits would be skipped
|
||||
# under lefthook but is a no-op for the sync-staleness warning
|
||||
# anyway, so behaviour stays effectively 1:1.)
|
||||
git-lfs:
|
||||
# `git lfs install --skip-repo` only sets up global clean/smudge
|
||||
# filters — it does NOT install the per-repo pre-push hook
|
||||
# (which would conflict with lefthook). We delegate the LFS
|
||||
# upload step here so screenshot baselines tracked via LFS get
|
||||
# pushed alongside their commits.
|
||||
run: git lfs pre-push {1} {2}
|
||||
|
||||
Reference in New Issue
Block a user