Skip to content

fix(indexer): resolve git hooks dir via git, not hardcoded .git/hooks#53

Open
fazleelahhee wants to merge 2 commits intomainfrom
fix/git-hooks-worktree-support
Open

fix(indexer): resolve git hooks dir via git, not hardcoded .git/hooks#53
fazleelahhee wants to merge 2 commits intomainfrom
fix/git-hooks-worktree-support

Conversation

@fazleelahhee
Copy link
Copy Markdown
Contributor

Summary

Partially addresses #48.

install_hooks and cce uninstall both assumed <project>/.git/hooks/ is always a directory. In a git worktree, <project>/.git is a file (gitfile pointer) and the hooks live in the shared main-repo .git/hooks/. The old path check silently no-op'd, so installing or uninstalling from inside a worktree did nothing.

Use git rev-parse --git-path hooks to resolve the right directory in both regular checkouts and worktrees, and to honor core.hooksPath if set. Refactor: extract uninstall_hooks(project_dir) so cli.py shares the same resolver.

The storage-key collision item from #48 is split into a follow-up issue (#52) since it touches 30+ call sites and needs a one-time migration.

Test plan

  • Existing fake-.git/hooks/ fixture replaced with a real git init repo (the previous fixture silently masked the production path).
  • New worktree fixture (git worktree add) pins both install and uninstall behavior from inside a worktree.
  • Tests skip cleanly when the git binary is unavailable.
  • All 158 indexer + uninstall tests pass.
  • Lint clean (ruff check).

Files

  • src/context_engine/indexer/git_hooks.py — new _resolve_hooks_dir() helper using git rev-parse --git-path hooks; install_hooks and new uninstall_hooks both go through it.
  • src/context_engine/cli.pycce uninstall now calls uninstall_hooks instead of walking .git/hooks/ inline.
  • tests/indexer/test_git_hooks.py — real git-repo fixture, new worktree fixture, 5 new test cases covering worktree install/uninstall and content-based hook detection.

`install_hooks` and the inline uninstall logic in `cce uninstall` both
assumed `<project>/.git/hooks/` is always a real directory. In a git
worktree, `<project>/.git` is a *file* (gitfile pointer) and the actual
hooks live in the shared main-repo `.git/hooks/`. The old path check
silently no-op'd, so installing or uninstalling from inside a worktree
did nothing — no auto-reindex hook fired on commit, and uninstall
appeared successful while leaving hooks in place.

Use `git rev-parse --git-path hooks` to resolve the real directory.
That returns the relative `.git/hooks` for regular checkouts, the
absolute path to the shared main-repo hooks dir for worktrees, and
respects `core.hooksPath` if a project has overridden it. Same code
path for both install and uninstall.

Refactor: extract a new `uninstall_hooks(project_dir)` in
`indexer/git_hooks.py` so the cli.py uninstall command shares the
worktree-aware resolver. cli.py is now three lines instead of a
hand-rolled directory walk.

Tests:
- Convert the existing fake-`.git/hooks/` fixture to a real `git init`
  repo so the resolver is exercised end-to-end (the previous fixture
  silently masked the production path).
- New worktree fixture (`git worktree add`) pins both the install and
  uninstall behavior: from a worktree, both must operate on the
  shared main-repo hooks dir.
- Skip the file when git binary is unavailable (matches `_resolve_hooks_dir`
  graceful return-None contract).

Partially addresses #48 — the storage-key collision item from that
issue is left for a follow-up since it touches 30+ call sites and
needs a one-time migration.
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.

2 participants