Home

Awesome

Summarize git repo info into shell variables

This is designed to replace multiple calls to git with a single use of eval $(git-status-vars). It’s especially useful for generating a shell prompt.

This is intended to be generally usable in any theme that wants to report git information in any shell with sh-like strings. I use it in my personal ZSH theme.

Installation

You can download binaries from the GitHub releases page. Just extract them and copy the file inside into your $PATH, e.g. /usr/local/bin. The most common ones are:

If you have cargo, you can just do cargo install git-status-vars to install from source, or if you’ve installed cargo binstall you can use that (cargo binstall git-status-vars).

Release status

Usage

eval $(git-status-vars 2>/dev/null)
if [[ $repo_state == "NotFound" ]] ; then
  return 0
fi

This outputs a bunch of sh compatible environment variables about the current repository. The repository is found by looking at each of the following in order and taking the first that matches:

  1. Command line parameter. A repository directory, or a subdirectory of a repository, may be passed on the command line.
  2. The $GIT_DIR environment variable, just like git.
  3. A .git directory in the working directory or one of its parents.

git-status-vars will always output repo_state=, but all other variables may be left out. In particular, if it can’t find a repository, it will output only repo_state=NotFound.

Example prompt function with git-status-vars

git_prompt () {
  eval $(git-status-vars 2>/dev/null)
  if [[ $repo_state == "NotFound" ]] ; then
    return 0
  fi

  local fg_color=green
  if (( $untracked_count > 0 )) ; then
    fg_color=red
  fi

  local ref=$head_ref1_short
  if [[ -z $ref ]] ; then
    ref=${head_hash:0:8}
  fi

  print -Pn "%F{$fg_color}${ref}%f "
}

Equivalent prompt function without git-status-vars

git_prompt () {
  setopt local_options pipefail
  local untracked_count fg_color=green
  untracked_count=$(git ls-files --other --exclude-standard 2>/dev/null | wc -l)
  if (( $? != 0 )) ; then
    # No repository
    return 0
  fi

  local fg_color=green
  if (( $untracked_count > 0 )) ; then
    fg_color=red
  fi

  # Try for the branch or tag name, then try for the commit hash
  ref=$(git symbolic-ref --short HEAD 2>/dev/null) \
    || ref="$(git show-ref --head --hash --abbrev HEAD 2>/dev/null | head -n1)"

  print -Pn "%F{$fg_color}${ref}%f "
}

Typical output

~/projects/git-status-vars ❯ git-status-vars
repo_state=Clean
repo_workdir=/Users/daniel/projects/git-status-vars/
repo_empty=false
repo_bare=false
head_ref_length=1
head_ref1_name=refs/heads/main
head_ref1_short=main
head_ref1_kind=direct
head_ref1_error=''
head_hash=2df6b768e60fbf899d8c8dc4a20385f30ee5da24
head_ahead=0
head_behind=0
head_upstream_error=''
untracked_count=0
unstaged_count=0
staged_count=0
conflicted_count=0
~/projects/git-status-vars ❯ cd /
/ ❯ git-status-vars
repo_state=NotFound

Performance

git-status-vars is generally faster than multiple calls to git, though git is fast enough that the difference will not usually be perceptible. On my laptop git-status-vars typically runs in around 8 ms whereas the fallback code involving multiple calls to git takes around 25 ms.

I have not tested this on large repositories.

Rust Crate

docs.rs Crates.io Rust version 1.64+

I’m not sure how useful it is, but this may be used from other Rust code.

Currently the minimum supported Rust version (MSRV) is 1.74.1.

Development and contributions

See DEVELOPMENT.md for notes on contributing to this repo, the license, how changes are tracked, and how releases are made.

Development status

This is stable. I don’t have plans for additional features, but if you have ideas please either submit an issue or a pull request.

I will periodically update this to ensure that it doesn’t bit rot as dependencies are updated, but you should not expect active development.