1<h1><img src="screenshot.svg" width="800" /></h1> 2 3A fast, customizable, pure-shell, asynchronous Git prompt for Zsh. 4It is heavily inspired by Olivier Verdier's [zsh-git-prompt](https://github.com/olivierverdier/zsh-git-prompt) and very similar to the "Informative VCS" prompt of fish shell. 5 6## Prompt Structure 7The structure of the prompt (in the default configuration) is the following: 8 9``` 10[<branch_name><upstream><tracking_status>|<local_status>] 11``` 12 13* `branch_name`: Name of the current branch or commit hash if HEAD is detached. When in 'detached HEAD' state, the 14 `branch_name` will be prefixed with a colon `:` to indicate that it is actually a hash and not a branch name. 15* `upstream`: Name of the remote branch if it exist. 16 Must be enabled explicitly (see [Enable remote branch info](#enable-remote-branch-info)). 17* `tracking_status`: 18 * `↑n`: ahead of remote by `n` commits 19 * `↓n`: behind remote by `n` commits 20 * `↓m↑n`: branches diverged; other by `m` commits, yours by `n` commits 21* `local_status`: 22 * `✔`: repository is clean 23 * `✖n`: there are `n` unmerged files 24 * `●n`: there are `n` staged files 25 * `✚n`: there are `n` unstaged and changed files 26 * `…n`: there are `n` untracked files 27 * `⚑n`: there are `n` entries on the stash (disabled by default) 28 29## Installation 30### Dependencies 31* Git with `--porcelain=v2` support, which is available since version 2.11.0. 32 You can check if your installation is compatible by executing `git status --branch --porcelain=v2` inside a Git repository. 33* [awk](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html), which is most certainly preinstalled on any \*nix system 34 35### [Zplug](https://github.com/zplug/zplug) 36Either install the default prompt (see [Examples](#examples) section below) with 37``` 38# Installs the "default" example 39zplug "woefe/git-prompt.zsh" 40``` 41or choose an example prompt with 42``` 43# Installs the "multiline" example 44zplug "woefe/git-prompt.zsh", use:"{git-prompt.zsh,examples/multiline.zsh}" 45``` 46 47### [Zplugin](https://github.com/zdharma/zplugin) 48``` 49zplugin ice atload'!_zsh_git_prompt_precmd_hook' lucid 50zplugin load woefe/git-prompt.zsh 51``` 52Note that this method does not work if you want to disable the asynchronous rendering. 53 54### Arch Linux 55Install [git-prompt.zsh](https://aur.archlinux.org/packages/git-prompt.zsh/) or [git-prompt.zsh-git](https://aur.archlinux.org/packages/git-prompt.zsh-git/) from the AUR. Maintained by [Felixoid](https://github.com/Felixoid). 56 57### FreeBSD 58Install the [git-prompt.zsh](https://www.freshports.org/shells/git-prompt.zsh/) package with 59``` 60pkg install git-prompt.zsh 61``` 62 63### Manual installation 64Clone this repo or download the [git-prompt.zsh](https://raw.githubusercontent.com/woefe/zsh-git-prompt/master/git-prompt.zsh) file. 65Then source it in your `.zshrc`. For example: 66 67```bash 68mkdir -p ~/.zsh 69git clone --depth=1 https://github.com/woefe/git-prompt.zsh ~/.zsh/git-prompt.zsh 70echo "source ~/.zsh/git-prompt.zsh/git-prompt.zsh" >> .zshrc 71 72# Optional: install an example configuration 73echo "source ~/.zsh/git-prompt.zsh/examples/pure.zsh" >> .zshrc 74``` 75 76## Customization 77Unlike other popular prompts this prompt does not use `promptinit`, which gives you the flexibility to build your own prompt from scratch. 78You can build a custom prompt by setting the `PROMPT` variable in your `.zshrc` after souring the `git-prompt.zsh`. 79And you should use `'$(gitprompt)'` in your `PROMPT` to get the Git prompt. 80You must set your `PROMPT` with **single quotes**, not double quotes, otherwise the Git prompt will not update properly. 81Some example `PROMPT` configurations are given below. 82You can find more information on how to configure the `PROMPT` in [Zsh's online documentation](http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html) or the `zshmisc` manpage, section "SIMPLE PROMPT ESCAPES". 83 84### Examples 85You can try these configurations by souring the `.zsh` files from the [examples](./examples) directory. 86After you have found a configuration that you like, source it in your `.zshrc`. 87 88#### Default (same as in title) 89```zsh 90# Preview: 91# ../git-prompt.zsh [master↑1|●1✚1…1] ❯❯❯ 92 93source examples/default.zsh 94``` 95 96#### Multi-line prompt 97```zsh 98# Preview: 99# ┏╸130 · ~/workspace/git-prompt.zsh · ⎇ master↑1 ‹●1✚1…1› 100# ┗╸❯❯❯ 101 102source examples/multiline.zsh 103``` 104 105#### Git status on the right 106```zsh 107# Preview: 108# ~/workspace/git-prompt.zsh ≻≻≻ ≺ master↑1|●1✚1…1 109 110source examples/rprompt.zsh 111``` 112 113#### [Pure](https://github.com/sindresorhus/pure) clone 114This clone of the Pure prompt has support for Python virtualenvs, but none of the timing features or a vi mode. 115If you are using [fzf](https://github.com/junegunn/fzf), source the example after sourcing fzf's keybindings. 116```zsh 117# Preview: 118# 119# ~/workspace/git-prompt.zsh master↑3 ✚2…1 120# ❯ 121 122source examples/pure.zsh 123``` 124If you want to try other examples again after sourcing the Pure example, you might have to restart your shell, because this prompt will always print a newline between prompts. 125 126#### Woefe's prompt (wprompt) 127The wprompt example is similar to the multi-line and Pure examples, but with optional [vi-mode](https://github.com/woefe/vi-mode.zsh) and the secondary prompt enabled. 128 129- Depends on [Font Awesome](https://fontawesome.com/) for the Python symbol 130- Optionally depends on [vi-mode](https://github.com/woefe/vi-mode.zsh) 131- Source this example after fzf and after loading [vi-mode](https://github.com/woefe/vi-mode.zsh) 132 133```zsh 134# Preview: 135# 136# ┏╸~/workspace/ytcc · ytcc · ⎇ master ‹✔› 137# ┗╸❯❯❯ 138 139source examples/wprompt.zsh 140``` 141If you want to try other examples again after sourcing this example, you might have to restart your shell, because this prompt will always print a newline between prompts. 142 143### Enable secondary prompt 144The prompt comes with a secondary function that shows the tags that HEAD points to. 145Enabling this will execute another Git command every time a new prompt is shown! 146To use the secondary prompt you have to enable it and add the `'gitprompt_secondary'` function to your `PROMPT` or `RPROMPT` variables. 147You enable the secondary prompt by adding the following line to your `.zshrc`: 148 149```bash 150ZSH_GIT_PROMPT_ENABLE_SECONDARY=1 151``` 152 153The secondary prompt uses the [label emoji](https://emojipedia.org/label/) by default. 154If you encounter problems with the label character, change it (see below) or install a font that can display it, for example [Unifont](https://savannah.gnu.org/projects/unifont) or [twemoji](https://github.com/eosrei/twemoji-color-font). 155 156### Appearance 157The appearance of the prompt can be adjusted by changing the variables that start with `ZSH_THEME_GIT_PROMPT_`. 158Note that some of them are named differently than in the original Git prompt by Olivier Verdier. 159 160You can preview your configuration by setting the `ZSH_THEME_GIT_PROMPT_*` variables in a running shell. 161But remember to save them in your `.zshrc` after you tweaked them to your liking! 162Example snippet from `.zshrc`: 163 164```zsh 165# Theming variables for primary prompt 166ZSH_THEME_GIT_PROMPT_PREFIX="[" 167ZSH_THEME_GIT_PROMPT_SUFFIX="] " 168ZSH_THEME_GIT_PROMPT_SEPARATOR="|" 169ZSH_THEME_GIT_PROMPT_DETACHED="%{$fg_bold[cyan]%}:" 170ZSH_THEME_GIT_PROMPT_BRANCH="%{$fg_bold[magenta]%}" 171ZSH_THEME_GIT_PROMPT_UPSTREAM_SYMBOL="%{$fg_bold[yellow]%}⟳ " 172ZSH_THEME_GIT_PROMPT_UPSTREAM_PREFIX="%{$fg[red]%}(%{$fg[yellow]%}" 173ZSH_THEME_GIT_PROMPT_UPSTREAM_SUFFIX="%{$fg[red]%})" 174ZSH_THEME_GIT_PROMPT_BEHIND="↓" 175ZSH_THEME_GIT_PROMPT_AHEAD="↑" 176ZSH_THEME_GIT_PROMPT_UNMERGED="%{$fg[red]%}✖" 177ZSH_THEME_GIT_PROMPT_STAGED="%{$fg[green]%}●" 178ZSH_THEME_GIT_PROMPT_UNSTAGED="%{$fg[red]%}✚" 179ZSH_THEME_GIT_PROMPT_UNTRACKED="…" 180ZSH_THEME_GIT_PROMPT_STASHED="%{$fg[blue]%}⚑" 181ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}✔" 182 183# Theming variables for the secondary prompt 184ZSH_THEME_GIT_PROMPT_SECONDARY_PREFIX="" 185ZSH_THEME_GIT_PROMPT_SECONDARY_SUFFIX="" 186ZSH_THEME_GIT_PROMPT_TAGS_SEPARATOR=", " 187ZSH_THEME_GIT_PROMPT_TAGS_PREFIX=" " 188ZSH_THEME_GIT_PROMPT_TAGS_SUFFIX="" 189ZSH_THEME_GIT_PROMPT_TAG="%{$fg_bold[magenta]%}" 190source path/to/git-prompt.zsh 191``` 192 193### Enable remote branch info 194The prompt will show information about the remote branch, if `ZSH_GIT_PROMPT_SHOW_UPSTREAM` is set to `full` or `symbol`. 195The `full` option will print the full remote branch name enclosed by `ZSH_THEME_GIT_PROMPT_UPSTREAM_PREFIX` and `ZSH_THEME_GIT_PROMPT_UPSTREAM_SUFFIX`. 196The `symbol` option prints only `ZSH_THEME_GIT_PROMPT_UPSTREAM_SYMBOL`. 197 198### Show number of stash entries 199The number of stash entries will be shown if `ZSH_GIT_PROMPT_SHOW_STASH` is set. 200Enabling this will execute another Git command every time a new prompt is shown! 201To enable stash entries add the following line to your `.zshrc`: 202 203```bash 204ZSH_GIT_PROMPT_SHOW_STASH=1 205``` 206 207### Force blank 208Since the prompt is asynchronous by default, the Git status updates slightly delayed. 209This has the benefit that the prompt will always be responsive even if the repository is huge and/or your disk is slow. 210But it also means that the old status will be displayed for some time. 211You can force the prompt to blank out instead of displaying a potentially outdated status, but be warned that this will probably increase flickering. 212Set the following variable in your `.zshrc` to enable this behavior: 213 214```bash 215ZSH_GIT_PROMPT_FORCE_BLANK=1 216``` 217 218### Disable async 219If you are not happy with the asynchronous behavior, you can disable it altogether. 220But be warned that this can make your shell painfully slow if you enter large repositories or if your disk is slow. 221Set the following variable in your `.zshrc` **before** sourcing the `git-prompt.zsh` to enable this behavior. 222 223```bash 224ZSH_GIT_PROMPT_NO_ASYNC=1 225``` 226`ZSH_GIT_PROMPT_NO_ASYNC` cannot be adjusted in a running shell, but only in your `.zshrc`. 227 228### Change the awk implementation 229Some awk implementations are faster than others. 230By default, the prompt checks for [nawk](https://github.com/onetrueawk/awk) and then [mawk](https://invisible-island.net/mawk/) and then falls back to the system's default awk. 231You can override this behavior by setting `ZSH_GIT_PROMPT_AWK_CMD` to the awk implementation of you liking **before** sourcing the `git-prompt.zsh`. 232`ZSH_GIT_PROMPT_AWK_CMD` cannot be adjusted in a running shell, but only in your `.zshrc`. 233 234To benchmark an awk implementation you can use the following command. 235```bash 236# This example tests the default awk. You should change it to something else. 237time ZSH_GIT_PROMPT_AWK_CMD=awk zsh -f -c ' 238 source path/to/git-prompt.zsh 239 for i in $(seq 1000); do 240 print -P $(_zsh_git_prompt_git_status) 241 done' 242``` 243 244## Features / Non-Features 245* A pure shell implementation using [awk](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html); no Python, no Haskell required 246 <!-- Well, technically awk is its own programming language and therefore not "pure shell", but heh --> 247* Only the Git status. 248 This prompt basically only gives you the `gitprompt` function, which you can use to build your own prompt. 249 If you are looking for something more complete and blazing fast, I can recommend [powerlevel10k](https://github.com/romkatv/powerlevel10k). 250* Uses standard Git, no external Git status daemon (like [gitstatus](https://github.com/romkatv/gitstatus)) required 251* Fast; Git command is invoked only once and asynchronously when a new prompt is drawn 252* No caching feature, because it breaks reliable detection of untracked files 253 254## Known issues 255* If the current working directory is not a Git repository and some external application initializes a new repository in the same directory, the Git prompt will not be shown immediately. 256 Also, updates made by external programs or another shell do not show up immediately. 257 Executing any command or simply pressing enter will fix the issue. 258* In large repositories the prompt might slow down, because Git has to find untracked files. 259 See `man git-status`, Section `--untracked-files` for possible options to speed things up. 260