make hooks and make docker both fail when run from a git worktree #33

Open
opened 2026-08-09 04:11:48 +02:00 by clawbot · 0 comments
Collaborator

Problem

Two independent bugs make this repo hostile to git worktree checkouts. Both were hit during real work on PR #31 and cost time to diagnose and work around.

1. script/install-precommit writes to a path that does not exist in a worktree

The script writes .git/hooks/pre-commit directly. In a linked worktree, .git is a file containing a gitdir: pointer, not a directory — so there is no .git/hooks/ to write into:

cannot create .git/hooks/pre-commit: Directory nonexistent

make hooks therefore fails outright in any worktree.

The fix is one line: resolve the hooks directory with git rev-parse --git-common-dir instead of assuming the literal path. That returns the shared .git of the main checkout from inside a worktree, and the plain .git directory otherwise, so it is correct in both cases.

Note backend/Makefile's hooks target has the same flaw — it uses $(git rev-parse --show-toplevel)/.git/hooks/pre-commit, which is wrong for the same reason. That target is slated for removal in #16; if #16 lands first this half is moot, so check before duplicating work.

2. Dockerfile.backend's COPY .git /repo/.git breaks in a worktree

The Docker build copies .git so backend/Makefile's git describe can resolve a version. From a worktree, .git is the pointer file, so the copy produces something unusable and git describe fails inside the build. make docker cannot be run from a worktree at all.

This half is already addressed by #17, which replaces the .git copy with ARG VERSION per the mandated Go Dockerfile pattern. It is recorded here only so the two symptoms are documented together — do not fix it twice. If #17 lands first, close this half as resolved.

Why this matters beyond convenience

Worktrees are the standard isolation mechanism for concurrent work in this repo. Every implementer and reviewer is expected to work in one. Both of these bugs are hit on essentially every backend change, and the workarounds are non-obvious:

  • The PR #31 implementer had to clone the worktree to a scratch directory just to run the Docker gate.
  • Anyone running make setup in a worktree gets a hard failure on a target that is supposed to be routine.

That is a tax on every future change, and it invites a worse outcome: an agent that cannot run make docker from its worktree may skip the Docker gate rather than work around it, and a gate that is inconvenient enough to skip is not a gate.

Definition of done

  • script/install-precommit resolves the hooks directory via git rev-parse --git-common-dir (or equivalent) rather than the literal .git/hooks path.
  • make hooks succeeds from a linked worktree and from a normal clone. Verify both explicitly and report both results.
  • The installed hook is functional in both cases — not merely created. Make a trivial commit in each and confirm the hook actually runs.
  • make docker succeeds from a linked worktree. If #17 has already landed, verify this still holds rather than re-implementing; if it has not, coordinate — say in the PR which issue you are relying on.
  • If backend/Makefile's hooks target still exists at implementation time, it gets the same fix or is removed per #16.
  • make check passes at the root and in backend/.
  • TODO.md updated in the same commit.
  • Commit title ends with (closes #N).

Implementation requirements

  • script/ files stay POSIX sh: #!/bin/sh, set -eu, no bashisms.
  • script/install-precommit is close to a model script shared across repos — if the fix is generally correct (it is), note in the PR that it is worth upstreaming to sneak/prompts rather than diverging here. See #28, which tracks script drift from the models.
  • Do not silently swallow errors. If the hooks directory genuinely cannot be resolved, fail loudly.
  • make targets and script/ entrypoints only.
  • No attribution trailers in the commit message.
## Problem Two independent bugs make this repo hostile to `git worktree` checkouts. Both were hit during real work on PR #31 and cost time to diagnose and work around. ### 1. `script/install-precommit` writes to a path that does not exist in a worktree The script writes `.git/hooks/pre-commit` directly. In a linked worktree, `.git` is a **file** containing a `gitdir:` pointer, not a directory — so there is no `.git/hooks/` to write into: ``` cannot create .git/hooks/pre-commit: Directory nonexistent ``` `make hooks` therefore fails outright in any worktree. The fix is one line: resolve the hooks directory with `git rev-parse --git-common-dir` instead of assuming the literal path. That returns the shared `.git` of the main checkout from inside a worktree, and the plain `.git` directory otherwise, so it is correct in both cases. Note `backend/Makefile`'s `hooks` target has the same flaw — it uses `$(git rev-parse --show-toplevel)/.git/hooks/pre-commit`, which is wrong for the same reason. That target is slated for removal in #16; if #16 lands first this half is moot, so check before duplicating work. ### 2. `Dockerfile.backend`'s `COPY .git /repo/.git` breaks in a worktree The Docker build copies `.git` so `backend/Makefile`'s `git describe` can resolve a version. From a worktree, `.git` is the pointer **file**, so the copy produces something unusable and `git describe` fails inside the build. `make docker` cannot be run from a worktree at all. **This half is already addressed by #17**, which replaces the `.git` copy with `ARG VERSION` per the mandated Go Dockerfile pattern. It is recorded here only so the two symptoms are documented together — do not fix it twice. If #17 lands first, close this half as resolved. ## Why this matters beyond convenience Worktrees are the standard isolation mechanism for concurrent work in this repo. Every implementer and reviewer is expected to work in one. Both of these bugs are hit on essentially every backend change, and the workarounds are non-obvious: - The PR #31 implementer had to clone the worktree to a scratch directory just to run the Docker gate. - Anyone running `make setup` in a worktree gets a hard failure on a target that is supposed to be routine. That is a tax on every future change, and it invites a worse outcome: an agent that cannot run `make docker` from its worktree may skip the Docker gate rather than work around it, and a gate that is inconvenient enough to skip is not a gate. ## Definition of done - [ ] `script/install-precommit` resolves the hooks directory via `git rev-parse --git-common-dir` (or equivalent) rather than the literal `.git/hooks` path. - [ ] `make hooks` succeeds from a linked worktree **and** from a normal clone. Verify both explicitly and report both results. - [ ] The installed hook is functional in both cases — not merely created. Make a trivial commit in each and confirm the hook actually runs. - [ ] `make docker` succeeds from a linked worktree. If #17 has already landed, verify this still holds rather than re-implementing; if it has not, coordinate — say in the PR which issue you are relying on. - [ ] If `backend/Makefile`'s `hooks` target still exists at implementation time, it gets the same fix or is removed per #16. - [ ] `make check` passes at the root and in `backend/`. - [ ] `TODO.md` updated in the same commit. - [ ] Commit title ends with ` (closes #N)`. ## Implementation requirements - `script/` files stay POSIX sh: `#!/bin/sh`, `set -eu`, no bashisms. - `script/install-precommit` is close to a model script shared across repos — if the fix is generally correct (it is), note in the PR that it is worth upstreaming to `sneak/prompts` rather than diverging here. See #28, which tracks script drift from the models. - Do not silently swallow errors. If the hooks directory genuinely cannot be resolved, fail loudly. - `make` targets and `script/` entrypoints only. - No attribution trailers in the commit message.
clawbot added this to the 1.0.0 milestone 2026-08-09 04:11:48 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/netwatch#33