entireio / entireio/cli

entire and lefthook fight over the pre-push hook; session push gets silently disabled

Open
#1,349 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Go
Stars
5.1k
Forks
475
Avg merge
1d 11h
Merged PRs (30d)
178

Description

What happened?

In a repo that also uses lefthook to manage git hooks, entire and lefthook fight over .git/hooks/pre-push. After any change to lefthook.yml, lefthook silently reclaims the hook and entire's session-log-on-push stops working — with no error — until someone manually re-wraps it.

How the conflict arises

  1. lefthook installs and manages pre-push. Its installed hooks self-sync on every run, gated by a checksum of lefthook.yml stored in .git/info/lefthook.checksum.
  2. entire enable / entire configure --force wraps the existing hook: it renames the current pre-push to pre-push.pre-entire and installs its own wrapper that runs the entire handler then chains down:
    # Entire CLI hooks
    if command -v entire >/dev/null 2>&1; then entire hooks git pre-push "$1" || true; else :; fi
    # Chain: run pre-existing hook
    "$(dirname "$0")/pre-push.pre-entire" "$@"
    
    At this point both run on push — entire pushes session logs, then chains to lefthook. 👍
  3. But whenever lefthook.yml changes, lefthook's checksum goes stale. Its next self-sync (at the top of any lefthook-managed hook, e.g. the next commit's pre-commit) sees that pre-push is no longer its hook, backs entire's wrapper up to pre-push.old, and reinstalls its own bare hook. entire's session push is now silently gone.
  4. On the next lefthook.yml change after that, lefthook also emits a recurring warning, because its earlier backup collides:
    sync hooks: ❌
    could not replace the hook: can't rename pre-push to pre-push.old - file already exists
    

Why there is no clean user-side fix (verified on 0.7.3)

The natural fix — make lefthook the sole owner of pre-push and run entire's push as a lefthook job/script — is blocked:

  • entire configure --force re-installs entire's pre-push wrapper even with push_sessions: false → you cannot stop entire owning the hook.
  • entire hooks git pre-push <remote> is itself gated by push_sessions (no-ops when off) → you cannot disable the wrapper and still call the handler from a lefthook script.
  • entire configure --force re-wraps whatever is at pre-push with no detection — if lefthook reclaimed it, entire silently wraps lefthook's bare hook again, with no idempotency check or "another manager owns this" warning.

The only local mitigation is a self-heal step that re-wraps after each re-sync, which still can't cover a push that happens with no intervening commit.

Proposed fixes (any one resolves it)

  1. Idempotent / manager-aware install — if pre-push already chains to pre-push.pre-entire (or contains entire's wrapper), don't blindly re-wrap; detect known managers (lefthook, husky, pre-commit, core.hooksPath).
  2. Decouple handler from install — an option to install the handler behavior without owning the pre-push file, so managers like lefthook can invoke entire hooks git pre-push as a job/script. (Today --skip-push-sessions disables the handler too, defeating this.)
  3. Register via the host manager — when lefthook is detected, register entire's push as a lefthook script (lefthook scripts receive the hook's $@, including the remote) instead of taking the file.
  4. Self-repair marker — let entire re-assert/repair its wrapper automatically so a reclaim heals without manual entire configure --force.
Steps to reproduce
  1. A repo using lefthook with a pre-push: section; run lefthook install.
  2. entire enable (wraps pre-push, chaining to lefthook).
  3. Edit lefthook.yml (any change) and make a commit or push.
  4. lefthook's self-sync reclaims pre-push; entire's session push silently stops (no error). Confirm with head .git/hooks/pre-push — the entire wrapper is gone.
Entire CLI version

Entire CLI 0.7.3

OS and architecture

macOS 26.5, arm64 (Darwin 25.5.0)

Agent

claude code

Terminal

ghostty

Logs / debug output

Additional context
  • lefthook 2.0.12; .entire/settings.json committed (team-wide setup), so this affects every macOS dev on the team using entire.
  • The 0.7.3 pre-push wrapper added a command -v entire guard (no-ops cleanly when entire is off-PATH) — good, but it does not address this ownership conflict.
  • Also reproduces across git worktrees, which share a single .git/hooks dir.
  • No log output to attach: the failure is silent (entire's hook is simply removed; nothing is logged).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the hook installation behavior around .git/hooks/pre-push, entire enable, and entire configure --force, then reproduce the conflict using lefthook.yml and lefthook install. Trace how the existing hook is renamed and chained, and verify that a lefthook sync preserves Entire's session push without backup collisions or silent removal.

Written by the indexing model from the issue text.

Assessment

Tech stack
git
Domain
cli, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.