hk pre-commit stash aborts the commit on a transient index.lock, no retry (partial commits) #1056
Unanswered
k0pernikus
asked this question in
Troubleshooting and Bug Reports
Replies: 1 comment
-
|
Thanks for the detailed report. I opened #1060 with a bounded fix for this:
PR: #1060 This comment was generated by Codex. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
On a partial commit — some paths staged, others left modified in the worktree — hk's
stash = "git"step shells outgit stash push --keep-index -m hk --include-untracked -- <paths>exactly once. If the worktree
index.lockis held by another process at that moment, the stashfails and hk aborts the entire commit. The contention is transient: re-running the commit succeeds
as soon as the lock is released, so hk fails on a condition it could recover from by waiting.
Steps to reproduce
Deterministic repro (pins hk 1.50.0 via mise, runs in CI):
https://github.com/k0pernikus/hk-partial-commit-index-lock-repro
.git/index.lockwhile hk's pre-commit stash runs (standing in for a concurrent gitprocess, an editor's git integration, or fsmonitor).
bash reproduce.shexits non-zero when the bug reproduces, so the CI run is red:https://github.com/k0pernikus/hk-partial-commit-index-lock-repro/actions/runs/29118283285
Expected vs actual
Expected: a transient
index.lock— held briefly by another process, then released — does notabort the commit. hk tolerates the momentary contention instead of failing on the first attempt, and
fails loud only if the lock persists.
Actual: hk issues
git stash pushonce, propagates the firstindex.lock: File existserror,and aborts. No commit is created; the staged changes remain staged.
Root cause
push_stashinsrc/git.rsruns the shellgit stash pushand propagates the first error with noretry, backoff, or lock-wait. On a partial commit the tracked-subset branch takes the shell path —
src/git.rsL842-L853 (jdx/hk@860bda7):cmd.run()?fails the whole hook on the firstindex.lockerror. The other two shell-stash sitescarry the same no-retry
run(): the libgit2 fallback(L875-L879)
and the no-repo path
(L892-L903).
Full-file commits instead take the libgit2 stash
(
repo.stash_save, L862),which never acquires
index.lockthrough the CLI and is unaffected. This region is unchanged fromthe reproduced
v1.50.0to currentmain(860bda7).Possible fixes
The case is a transient, recoverable
index.lockcontention during a partial-commit stash — thekind a developer resolves by re-running the commit. Any of these would address it:
loudly if it outlasts the window.
are sub-second.
#247 / #234.
Environment
stash = "git", committing inside a git worktreeRelated discussions
Beta Was this translation helpful? Give feedback.
All reactions