Skip to content

Instantly share code, notes, and snippets.

@joshdick
Last active February 12, 2024 04:16
Show Gist options
  • Save joshdick/4415470 to your computer and use it in GitHub Desktop.
Save joshdick/4415470 to your computer and use it in GitHub Desktop.
My Git prompt for zsh.
# Adapted from code found at <https://gist.github.com/1712320>.
setopt prompt_subst
autoload -U colors && colors # Enable colors in prompt
# Modify the colors and symbols in these variables as desired.
GIT_PROMPT_SYMBOL="%{$fg[blue]%}±"
GIT_PROMPT_PREFIX="%{$fg[green]%}[%{$reset_color%}"
GIT_PROMPT_SUFFIX="%{$fg[green]%}]%{$reset_color%}"
GIT_PROMPT_AHEAD="%{$fg[red]%}ANUM%{$reset_color%}"
GIT_PROMPT_BEHIND="%{$fg[cyan]%}BNUM%{$reset_color%}"
GIT_PROMPT_MERGING="%{$fg[magenta]%}⚡︎%{$reset_color%}"
GIT_PROMPT_UNTRACKED="%{$fg[red]%}●%{$reset_color%}"
GIT_PROMPT_MODIFIED="%{$fg[yellow]%}●%{$reset_color%}"
GIT_PROMPT_STAGED="%{$fg[green]%}●%{$reset_color%}"
# Show Git branch/tag, or name-rev if on detached head
parse_git_branch() {
(git symbolic-ref -q HEAD || git name-rev --name-only --no-undefined --always HEAD) 2> /dev/null
}
# Show different symbols as appropriate for various Git repository states
parse_git_state() {
# Compose this value via multiple conditional appends.
local GIT_STATE=""
local NUM_AHEAD="$(git log --oneline @{u}.. 2> /dev/null | wc -l | tr -d ' ')"
if [ "$NUM_AHEAD" -gt 0 ]; then
GIT_STATE=$GIT_STATE${GIT_PROMPT_AHEAD//NUM/$NUM_AHEAD}
fi
local NUM_BEHIND="$(git log --oneline ..@{u} 2> /dev/null | wc -l | tr -d ' ')"
if [ "$NUM_BEHIND" -gt 0 ]; then
GIT_STATE=$GIT_STATE${GIT_PROMPT_BEHIND//NUM/$NUM_BEHIND}
fi
local GIT_DIR="$(git rev-parse --git-dir 2> /dev/null)"
if [ -n $GIT_DIR ] && test -r $GIT_DIR/MERGE_HEAD; then
GIT_STATE=$GIT_STATE$GIT_PROMPT_MERGING
fi
if [[ -n $(git ls-files --other --exclude-standard 2> /dev/null) ]]; then
GIT_STATE=$GIT_STATE$GIT_PROMPT_UNTRACKED
fi
if ! git diff --quiet 2> /dev/null; then
GIT_STATE=$GIT_STATE$GIT_PROMPT_MODIFIED
fi
if ! git diff --cached --quiet 2> /dev/null; then
GIT_STATE=$GIT_STATE$GIT_PROMPT_STAGED
fi
if [[ -n $GIT_STATE ]]; then
echo "$GIT_PROMPT_PREFIX$GIT_STATE$GIT_PROMPT_SUFFIX"
fi
}
# If inside a Git repository, print its branch and state
git_prompt_string() {
local git_where="$(parse_git_branch)"
[ -n "$git_where" ] && echo "$GIT_PROMPT_SYMBOL$(parse_git_state)$GIT_PROMPT_PREFIX%{$fg[yellow]%}${git_where#(refs/heads/|tags/)}$GIT_PROMPT_SUFFIX"
}
# Set the right-hand prompt
RPS1='$(git_prompt_string)'
@zanshin
Copy link

zanshin commented Jan 30, 2013

I like this approach to displaying git information in the prompt. However, when I implement this in my .zshrc the git_promtp_string is not getting cleared when I change to a non-git directory. I have to re-source the ~/.zshrc file to cause that to happen. Are you seeing that behavior in your implementation?

@massysett
Copy link

Very nice, thank you!

@massysett
Copy link

I just forked it and added some code to check and see if you're not on any branch and to color the branch red if so; but I haven't much idea how these gists work...

@joshdick
Copy link
Author

Apologies for the four months of silence, somehow I wasn't subscribed to notifications for my own Gist!

@joshdick
Copy link
Author

@zanshin For me, the prompt string is properly cleared for me when I switch to a non-Git directory.

How are you including the prompt in your .zshrc? You should be sourcing it:

. ~/.zsh/git-prompt/git_prompt.zsh

@joshdick
Copy link
Author

@massysett Glad you like it!

@tomswartz07
Copy link

@joshdick When you say to source it in your .zshrc; what do you mean, exactly?
I'm not quite sure if you mean to include this directly into the .zshrc or load it with an external file (and if it's the latter, how you do that...)

Thanks!

Copy link

ghost commented Oct 12, 2013

say if you downloaded this prompt and called it git-prompt.zsh and put it in your home folder ~/.

sourcing it in your .zshrc would be.

source ~/git-prompt.zsh

@briancline
Copy link

This is terrific -- thank you!

@aripollak
Copy link

Thanks for this, @joshdick! I made some changes in my fork to not set RPS1 by default so people can add it to their existing prompt wherever they want, and also to speed it up on directories with many files.

@ipozgaj
Copy link

ipozgaj commented Oct 23, 2014

Nice. The only bad thing about it is that the repos I'm working with are enormous, so this introduces a noticeable lag (like 2 seconds) every time I press enter (because git status is slow) :(

@chrisRidgers
Copy link

Very nice, don't suppose it could be made available for install via homebrew on OS X?

@joshdick
Copy link
Author

joshdick commented Jun 9, 2017

It has been a while, but I made some cosmetic tweaks and code cleanup to this prompt. Details here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment