hooks: never lose a hook when a backup already exists

Commit

peyton-alt23h ago

When a hook that isn't Entire's sits at a hook path and <hook>.pre-entire already exists (a hook manager reinstalled, the user edited it, a checkout restored it), install wrote Entire's hook over it and the newer hook was lost.

Now the current hook becomes the backup and the previous backup is kept as <hook>.pre-entire.<timestamp>, unless an identical older copy exists. Backups are made by hard link (or copy where links are unsupported), never by moving the hook away, so the hook path always holds a runnable hook and a crash at any step leaves every version on disk. Installs and removals take a lock in the git common dir, bounded to a second. Entire never chains to a backup that carries its own marker, which would make the hook call itself.

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com Entire-Checkpoint: 01M476BPYFTWKW40117J2293JT

Checkpoints

Triaging Git Hooks Tickets and Adversarial Review

Claude CodeOpus 5.5
View session
Checkpoint 1