github.com/bluz71/git-status-snap
0.2.0 / published Feb 5, 2025 / repository
A fast git status utility for custom prompts
git-status-snap
git-status-snap is a utility implemented in
Crystal that runs and parses git status to
constituent shell environment variables that can be sourced by a Bash, Zsh or
Fish script to render a fast Git-aware prompt.
Many custom prompts directly run and parse git status using shell commands.
However, parsing the output of git status using shell commands is much
slower than doing the same using optimized Crystal, often twice as slow
depending on the size of the repository.
Note, this utility is used to accelerate the bash-seafly-prompt.
Installation
Copy, and untar, the appropriate git-status-snap binary, from Releases, to
somewhere in the current $PATH.
Alternatively, if the Crystal build chain is available, clone this repository
and build a release via make and copy the git-status-snap binary from
bin/git-status-snap to somewhere in the current $PATH.
Requirements
Git version 2.11, released November 2016, or later is required.
Usage
In your prompt script source the output of git_status_snap to evaluate the current Git state.
In Bash or Zsh that would look as follows:
. <(git-status-snap)
And in Fish:
git-status-snap | source
Note, if using Fish just as an interactive shell, as opposed to a login shell,
please make sure that the SHELL environment variable is set to your running
version of the fish executable (for example /bin/fish).
Here is an example usage of git-status-snap in a very simple Bash prompt script:
_my_prompt() {
. <(git-status-snap)
if [[ -n $GSF_REPOSITORY ]]; then
PS1="\w $GSF_BRANCH> "
else
PS1="\w> "
fi
}
PROMPT_COMMAND=_my_prompt
Refer to the bash-seafly-prompt command script for a real-world usage of git-status-snap.
Implementation
git-status-snap will run the following git status command in the current
working directory:
git --no-optional-locks status --porcelain=v2 --branch --show-stash --ignore-submodules -uno
The result from that git status command will internally be parsed and
transformed to a series of shell environment variable statements, ready for
sourcing from a custom prompt script.
The relevant environment variables, using the GSF prefix (short for Git Status
Flag), will be:
| Environment Variable | Description | Value |
|---|---|---|
GSF_REPOSITORY | The current working directory is a Git repository | 1 |
GSF_BRANCH | The name of the current branch | String |
GSF_DIRTY | The index has unstaged changes | 1 |
GSF_STAGED | The index has staged changes | 1 |
GSF_UPSTREAM | Remote tracking differences exist | Refer below |
GSF_STASH | At least one stash exists | 1 |
GSF_UPSTREAM values:
-
0Current and remote branches are equal -
1Current branch is ahead of remote tracking branch -
-1Current branch is behind remote tracking branch -
2Current and remote branches have diverged
Note, the absence of any environment variable indicates falsehood, for example
if GSF_REPOSITORY is unset then that signals the current directory is not a
Git repository.
For performance reasons, untracked files and change counts are ignored.
Recommendations
Very large repositories, such as the Linux
kernel and the Chromium
browser, will result in slow git status
execution.
For such repositories, it is strongly recommended to enable the following configuration options directly in those very large repositories:
-
git config feature.manyFiles truewill adopt internal Git settings to improve performance for large repositories as documented here -
git config core.fsmonitor truewill enable Git file system monitor as documented here
Note, as of May 2023 fsmonitor is only available for Windows and macOS.
License
API
This version publishes no documented types.