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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions