Skip to content

hooks: skip rebuild in linked git worktrees#1806

Open
Claude-Madera wants to merge 1 commit into
Graphify-Labs:v8from
Claude-Madera:fix/skip-linked-worktrees
Open

hooks: skip rebuild in linked git worktrees#1806
Claude-Madera wants to merge 1 commit into
Graphify-Labs:v8from
Claude-Madera:fix/skip-linked-worktrees

Conversation

@Claude-Madera

Copy link
Copy Markdown

Problem

The post-commit and post-checkout hooks rebuild graphify-out/ on every commit and branch switch. Inside a linked worktree (git worktree add) this misbehaves:

  • The canonical graphify-out/ belongs to the primary checkout; rebuilding it from every worktree is wasteful.

  • Deploy/CI flows that create a worktree, switch/checkout, then git clean it, race the detached background rebuild against the cleanup — producing:

    failed to remove graphify-out/: Directory not empty
    

This surfaced in a deploy "cockpit" that pins release worktrees of three repos: every pin fired a pointless full rebuild and intermittently failed the git clean.

Fix

Guard both hooks: a linked worktree has git-dir != git-common-dir, so short-circuit before launching the rebuild.

Key correctness detail: the compare uses absolute paths —

_GFY_GITDIR=$(git rev-parse --absolute-git-dir 2>/dev/null)
_GFY_COMMONDIR=$(cd "$(git rev-parse --git-common-dir 2>/dev/null)" 2>/dev/null && pwd)
if [ -n "$_GFY_COMMONDIR" ] && [ "$_GFY_GITDIR" != "$_GFY_COMMONDIR" ]; then
    exit 0
fi

Git exports GIT_DIR to hooks and it is sometimes absolute; comparing a raw $GIT_DIR against a relative --git-common-dir (.git) would false-positive and wrongly skip the primary checkout. Resolving both to absolute paths avoids that. Factored into a shared _WORKTREE_GUARD constant, mirroring the existing _PYTHON_DETECT pattern.

Tests

  • test_hooks_skip_linked_worktrees — both generated scripts contain the guard exactly once and use the absolute-path compare.
  • test_worktree_guard_skips_only_linked_worktree — end-to-end against a real git worktree: the guard runs through on the primary checkout and exits early in a linked worktree.

Both pass; no previously-passing tests affected.

🤖 Generated with Claude Code

The post-commit and post-checkout hooks rebuild graphify-out/ on every
commit / branch switch. In a linked worktree (`git worktree add`) that is
wasteful -- the canonical graph belongs to the primary checkout -- and
deploy/CI flows that `git clean` a worktree race the detached rebuild
against the cleanup, producing 'failed to remove graphify-out/: Directory
not empty'.

Guard both hooks: a linked worktree has git-dir != git-common-dir. Compare
ABSOLUTE paths (git rev-parse --absolute-git-dir vs a resolved
--git-common-dir) so the GIT_DIR env var git exports to hooks -- sometimes
absolute -- cannot false-positive and skip the primary checkout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant