The hapin-z and hapin-z-light themes currently use zsh's built-in vcs_info (with check-for-changes true plus a +vi-git-untracked hook) to render git status. This is the largest contributor to prompt latency in flying-z.
Why this is slow on Cygwin
Each prompt redraw forks 3–4 git subprocesses:
git rev-parse --is-inside-work-tree (vcs_info)
git status for staged/unstaged
git rev-parse again (the untracked hook re-checks)
git ls-files --others --exclude-standard (untracked scan — very slow in repos with node_modules etc.)
On Cygwin each fork+exec costs ~50–100ms minimum, so a clean small repo pays ~200–400ms per prompt; large or noisy repos pay seconds. This shows up as the "cd hangs" symptom — the builtin cd actually completes fast, but the precmd vcs_info call blocks the prompt redraw.
Side note: DISABLE_UNTRACKED_FILES_DIRTY="true" in default.zshrc does not apply here — that flag only affects oh-my-zsh's parse_git_dirty, not vcs_info.
Proposed fix
Adopt romkatv/gitstatus — a single long-lived C daemon that:
- Spawns once at shell startup (one fork instead of N per prompt)
- Reads
.git directly via optimized C, no git CLI shelling
- Walks the working tree multi-threaded
- Returns results async over a pipe — prompt renders immediately, status fills in after
Published benchmarks on the linux kernel repo: vcs_info ~250ms vs gitstatus ~10ms. Cygwin's fork overhead widens that gap.
Implementation sketch
- Bundle the prebuilt Cygwin
gitstatusd binary (~1.5MB) and gitstatus.plugin.zsh from gitstatus releases into the flying-z installer (current installer is ~50MB so the size hit is negligible).
- Add a constant in
src/constants.mjs for the install path.
- Update the installer to copy them on install.
- Rewrite the VCS section of
assets/hapin-z.zsh-theme and assets/hapin-z-light.zsh-theme to source gitstatus.plugin.zsh, call gitstatus_start, and replace the vcs_info precmd hook + +vi-git-untracked with a gitstatus_query-driven prompt segment. Preserve the existing visual format (on branch ●✚).
- Verify the Cygwin daemon binary actually runs in flying-z's environment before committing to the install pipeline.
Resolves the existing # TODO: Investigate using gitstatus instead of vcs_info in assets/hapin-z.zsh-theme:35.
Out of scope for the original investigation branch
Tracked separately from the smaller wins on investigate-shell-slowdowns:
- Pure-zsh rewrite of the custom
cd function (drops 3 subshells per cd)
- Caching
cygpath -w "$PWD" in a chpwd hook so it stops running on every prompt redraw
The
hapin-zandhapin-z-lightthemes currently use zsh's built-invcs_info(withcheck-for-changes trueplus a+vi-git-untrackedhook) to render git status. This is the largest contributor to prompt latency in flying-z.Why this is slow on Cygwin
Each prompt redraw forks 3–4
gitsubprocesses:git rev-parse --is-inside-work-tree(vcs_info)git statusfor staged/unstagedgit rev-parseagain (the untracked hook re-checks)git ls-files --others --exclude-standard(untracked scan — very slow in repos withnode_modulesetc.)On Cygwin each fork+exec costs ~50–100ms minimum, so a clean small repo pays ~200–400ms per prompt; large or noisy repos pay seconds. This shows up as the "cd hangs" symptom — the
builtin cdactually completes fast, but the precmdvcs_infocall blocks the prompt redraw.Side note:
DISABLE_UNTRACKED_FILES_DIRTY="true"indefault.zshrcdoes not apply here — that flag only affects oh-my-zsh'sparse_git_dirty, notvcs_info.Proposed fix
Adopt
romkatv/gitstatus— a single long-lived C daemon that:.gitdirectly via optimized C, nogitCLI shellingPublished benchmarks on the linux kernel repo: vcs_info ~250ms vs gitstatus ~10ms. Cygwin's fork overhead widens that gap.
Implementation sketch
gitstatusdbinary (~1.5MB) andgitstatus.plugin.zshfrom gitstatus releases into the flying-z installer (current installer is ~50MB so the size hit is negligible).src/constants.mjsfor the install path.assets/hapin-z.zsh-themeandassets/hapin-z-light.zsh-themeto sourcegitstatus.plugin.zsh, callgitstatus_start, and replace thevcs_infoprecmd hook ++vi-git-untrackedwith agitstatus_query-driven prompt segment. Preserve the existing visual format (on branch ●✚).Resolves the existing
# TODO: Investigate using gitstatus instead of vcs_infoinassets/hapin-z.zsh-theme:35.Out of scope for the original investigation branch
Tracked separately from the smaller wins on
investigate-shell-slowdowns:cdfunction (drops 3 subshells percd)cygpath -w "$PWD"in achpwdhook so it stops running on every prompt redraw