Skip to content

Replace vcs_info with gitstatus in hapin-z theme for ~10-50x faster prompt #4

@Nantris

Description

@Nantris

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

  1. 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).
  2. Add a constant in src/constants.mjs for the install path.
  3. Update the installer to copy them on install.
  4. 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 ●✚).
  5. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions