Commit 8527fa0
committed
fix(hooks): a linked worktree is one whose git-dir differs from its git-common-dir
Both worktree-first guards decided "am I in a linked worktree?" by substring-matching
the git-dir path against `*/worktrees/*`. That is a test for the characters
`worktrees` appearing anywhere in a path, not a test for a linked worktree: a PRIMARY
checkout that merely lives under a directory named `worktrees` matched it, and both
guards allowed edits into a shared primary checkout — the exact failure worktree-first
exists to stop (see #11809).
The verdict was also depth-dependent, which is what made it reachable in practice.
`git rev-parse --git-dir` prints a RELATIVE `.git` at a repo toplevel and an ABSOLUTE
path from any subdirectory, and the guards hand git the edited file's nearest EXISTING
ancestor. So the same unguarded checkout blocked for a path resolving to the toplevel
and allowed for anything resolving to a subdirectory — and in a real repo almost every
edit is to a file in a subdirectory that already exists.
Replaced with the structural test: a linked worktree's git-dir (.git/worktrees/NAME)
differs from its git-common-dir (.git); a primary checkout has the two equal, and so
does a submodule (.git/modules/NAME for both), so neither needs a special case.
Two details are load-bearing and both are measured, not assumed:
* `--git-common-dir` prints RELATIVE to the directory queried (`.git` at a toplevel,
`../.git` from a subdirectory), so it must be resolved against that directory
before the comparison. Compared raw it never equals the absolute git-dir and the
guard fails open at EVERY depth — ablating just that line turns 47 matrix cases
from block to allow.
* `--absolute-git-dir` alone is NOT a fix. It removes the toplevel/subdirectory
asymmetry by making the guard fail open everywhere instead of somewhere.
Both sides are canonicalised through one helper so symlinked temp dirs and git's
relative printing cannot make two spellings of the same directory look different.
Self-tests: the four `worktrees`-segment cases are re-homed out of the KNOWN HOLE
section and all four now expect `block`; the Bash matrix gains that fixture and five
cases it never had. The non-vacuity recipe is re-aimed at the line that now exists,
so it is not a dead mutation.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox1 parent b31ebfe commit 8527fa0
4 files changed
Lines changed: 85 additions & 35 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
32 | 37 | | |
33 | 38 | | |
34 | 39 | | |
| |||
39 | 44 | | |
40 | 45 | | |
41 | 46 | | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
42 | 55 | | |
43 | 56 | | |
44 | 57 | | |
| |||
63 | 76 | | |
64 | 77 | | |
65 | 78 | | |
| 79 | + | |
66 | 80 | | |
67 | 81 | | |
68 | 82 | | |
| |||
110 | 124 | | |
111 | 125 | | |
112 | 126 | | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
113 | 140 | | |
114 | 141 | | |
115 | 142 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| |||
312 | 312 | | |
313 | 313 | | |
314 | 314 | | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
315 | 320 | | |
316 | 321 | | |
317 | | - | |
| 322 | + | |
318 | 323 | | |
319 | 324 | | |
320 | 325 | | |
| |||
334 | 339 | | |
335 | 340 | | |
336 | 341 | | |
337 | | - | |
338 | | - | |
339 | | - | |
340 | | - | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
341 | 351 | | |
342 | 352 | | |
343 | 353 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
131 | 131 | | |
132 | 132 | | |
133 | 133 | | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
134 | 138 | | |
135 | 139 | | |
136 | 140 | | |
| |||
363 | 367 | | |
364 | 368 | | |
365 | 369 | | |
366 | | - | |
367 | | - | |
368 | | - | |
369 | | - | |
370 | | - | |
371 | | - | |
372 | | - | |
373 | | - | |
374 | | - | |
375 | | - | |
376 | | - | |
377 | | - | |
378 | | - | |
379 | | - | |
380 | | - | |
381 | | - | |
382 | | - | |
383 | | - | |
384 | | - | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
385 | 385 | | |
386 | 386 | | |
387 | 387 | | |
| |||
403 | 403 | | |
404 | 404 | | |
405 | 405 | | |
406 | | - | |
| 406 | + | |
407 | 407 | | |
408 | 408 | | |
409 | | - | |
410 | | - | |
| 409 | + | |
| 410 | + | |
411 | 411 | | |
412 | 412 | | |
413 | 413 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
94 | 94 | | |
95 | 95 | | |
96 | 96 | | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
102 | 115 | | |
103 | 116 | | |
104 | 117 | | |
| |||
0 commit comments