#66210
Worktree creation hangs with a prek (post-checkout) hook
Reproduction steps
- Create a new Git repository and commit a single
prek.tomlfile to it:
# prek.toml
default_install_hook_types = ["post-checkout"]
[[repos]]
repo = "local"
hooks = [
{
id = "git-version",
name = "Print Git version",
entry = "git --version",
language = "system",
stages = ["post-checkout"],
always_run = true,
pass_filenames = false,
},
]-
Run
prek installfrom the root of the repository. -
Open the repository in Zed and try creating a new worktree using the top left worktree button.
Result: the worktree creation hangs. More precisely, the new checkout exists, but git worktree add waits on prek, which has a zombie child.
Possibly related:
- #44057
- #44212
- https://github.com/j178/prek/issues/718
P.S. The issue description and the minimal reproduction is drafted with LLM, and then fully reviewed and edited by myself.
Current vs. Expected behavior
Creating a worktree from the top-left worktree button leaves “Creating worktree…” spinning indefinitely instead of creating a new worktree and switching to it.
Zed version and system specs
- macOS 15.8.1
- Zed 1.25.3, build 20261023.131444
- Homebrew Git 2.56.0
- prek 0.5.7 (8569a4ac5)
Attach Zed log file
No response
Relevant Zed settings
settings.json
undefinedRelevant Keymap
keymap.json
undefined(for AI issues) Model provider details
No response
If you are using WSL on Windows, what flavor of Linux are you using?
None
I reproduced this on macOS 15.8.1 arm64 with Zed Nightly
1.27.0+nightly.3483.37faef81f74fc1bb08be9939c4cffc8ede6ced2f, prek0.5.7 (8569a4ac5)and Apple Git2.50.1.prek.tomlbelow and ranprek install.git: worktreefrom the command palette, entered a new worktree name and confirmed creation.The checkout existed, but Zed did not switch to it. The status bar kept showing
git worktree add (detached). Process snapshots at 1, 22 and 23 seconds showed Git waiting on prek, with a zombie child under prek. The editor remained responsive: I could open the command palette and filter its actions while the Git operation was stuck. I then stopped only the disposable prek process.I expected the trivial hook to finish and Zed to switch to the new worktree. Running
git worktree add --detachfrom the shell with the same installed hook completed successfully.Minimal prek.toml used
Additional controls and signal-mask observations
Replacing the hook with a plain shell script running
git --versionlet UI worktree creation finish and switch normally.In separate diagnostic runs, I used a Python wrapper to inspect the inherited signal mask before executing the same prek binary. Shell launches had an empty mask; Nightly launches had
SIGCHLDblocked. Preserving that mask completed in one run and hung with a zombie child in another. Unblocking onlySIGCHLDbefore executing prek let creation finish.This points toward inherited signal masking, but the masked runs were not deterministic. These were diagnostic controls, not a tested production fix. The original reproduction above used prek’s generated hook without that wrapper.
The worktree path still launches Git inside a background executor task in
create_worktree, whereas #44212 changed the separate direct-hook execution path.