To get a prompt which indicates Git-branch in Zsh
Solution 1
__git_ps1
is from git-completion.bash. In zsh you probably have to provide your own function to determine the current directories git branch. There are quite a few blog posts about a git prompt for zsh.
You just need:
- a function to provide the branch name
- enable prompt (command) substitution
- add the function to your prompt
For example
git_prompt() {
ref=$(git symbolic-ref HEAD | cut -d'/' -f3)
echo $ref
}
setopt prompt_subst
PS1=$(git_prompt)%#
autoload -U promptinit
promptinit
Update: use the zsh vcs_info module instead of git_prompt()
setopt prompt_subst
autoload -Uz vcs_info
zstyle ':vcs_info:*' actionformats \
'%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f '
zstyle ':vcs_info:*' formats \
'%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{5}]%f '
zstyle ':vcs_info:(sv[nk]|bzr):*' branchformat '%b%F{1}:%F{3}%r'
zstyle ':vcs_info:*' enable git cvs svn
# or use pre_cmd, see man zshcontrib
vcs_info_wrapper() {
vcs_info
if [ -n "$vcs_info_msg_0_" ]; then
echo "%{$fg[grey]%}${vcs_info_msg_0_}%{$reset_color%}$del"
fi
}
RPROMPT=$'$(vcs_info_wrapper)'
Solution 2
A lot of these solutions seemed slow for me when mashing the return key, so here's an option that is basic and speedy:
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
setopt PROMPT_SUBST
PROMPT='%9c%{%F{green}%}$(parse_git_branch)%{%F{none}%} $ '
You'll get a prompt that looks like this:
~/dev/project (feature-branch) $
Solution 3
Here is an extended git prompt for zsh: zsh-git-prompt.
Solution 4
ko-dos's answer is great, but I prefer a slightly more git aware prompt than the one he uses. Specifically, I like staged, unstaged, and untracked file notifications in the prompt itself. Using his answer and the zsh vcs_info examples, I came up with the following:
setopt prompt_subst
autoload -Uz vcs_info
zstyle ':vcs_info:*' stagedstr 'M'
zstyle ':vcs_info:*' unstagedstr 'M'
zstyle ':vcs_info:*' check-for-changes true
zstyle ':vcs_info:*' actionformats '%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f '
zstyle ':vcs_info:*' formats \
'%F{5}[%F{2}%b%F{5}] %F{2}%c%F{3}%u%f'
zstyle ':vcs_info:git*+set-message:*' hooks git-untracked
zstyle ':vcs_info:*' enable git
+vi-git-untracked() {
if [[ $(git rev-parse --is-inside-work-tree 2> /dev/null) == 'true' ]] && \
[[ $(git ls-files --other --directory --exclude-standard | sed q | wc -l | tr -d ' ') == 1 ]] ; then
hook_com[unstaged]+='%F{1}??%f'
fi
}
precmd () { vcs_info }
PROMPT='%F{5}[%F{2}%n%F{5}] %F{3}%3~ ${vcs_info_msg_0_} %f%# '
This creates a prompt that mimics the colorized output of git status -s
(which can be configured in your .gitconfig
file). A picture is perhaps most helpful here:
Compared with git status -s
:
If you don't like colorized output, or would prefer some other character or prompt construction, just change the stagedstr
, unstagedstr
, and hook_com[unstaged]
values in the above code.
Solution 5
I just redid mine since we have long branch names at work. This one will truncate with an ellipsis if it's more than 35 characters.
parse_git_branch() {
git_status="$(git status 2> /dev/null)"
pattern="On branch ([^[:space:]]*)"
if [[ ! ${git_status} =~ "(working (tree|directory) clean)" ]]; then
state="*"
fi
if [[ ${git_status} =~ ${pattern} ]]; then
branch=${match[1]}
branch_cut=${branch:0:35}
if (( ${#branch} > ${#branch_cut} )); then
echo "(${branch_cut}…${state})"
else
echo "(${branch}${state})"
fi
fi
}
setopt PROMPT_SUBST
PROMPT='%{%F{blue}%}%9c%{%F{none}%}$(parse_git_branch)$'
(I'm embarrassed at how proud I am of this.)
Comments
-
Michal aka Miki almost 2 years
I run the following codes separately as my prompt unsuccessfully in .zshrc. This suggests me that apparently I do not have a program called __git_ps1. It is not in MacPorts.
#1
PROMPT="$(__git_ps1 " \[\033[1;32m\] (%s)\[\033[0m\]")\$"$
#2
PROMPT="$(__git_ps1 " (%s)")\$"$
#3
# Get the name of the branch we are on git_prompt_info() { branch_prompt=$(__git_ps1) if [ -n "$branch_prompt" ]; then status_icon=$(git_status) echo $branch_prompt $status_icon fi } # Show character if changes are pending git_status() { if current_git_status=$(git status | grep 'added to commit' 2> /dev/null); then echo "☠" fi } autoload -U colors colors setopt prompt_subst PROMPT=' %~%{$fg_bold[black]%}$(git_prompt_info) → %{$reset_color%}'
How can you get a prompt which shows the name of a Git-branch?
-
Anonigan almost 15 yearsDo not use git-branch. It is porcelain, meant for UI, not for scripting. Use git-symbolic-ref and BR=${BR#refs/heads/}
-
Michal aka Miki almost 15 years@Jakub: Thank you for pointing that out! --- I just observed that git-branch causes bugs with non-git directories.
-
Justin Force almost 12 yearsLove it! Perfect. Very nice work, and now a submodule in my own dotfiles repo. :)
-
drizzt over 11 yearsgit_prompt is wrong, if you have a branch with / it does not work. Use
cut -d'/' -f3-
instead. -
balki about 11 yearsThanks!, this works. Can you please explain what those cryptic zstyle commands do?
-
harm about 11 yearsHow does your approach compare to vcs_info? It seems that your script is reinventing the wheel? (Didn't stop me from using it though, I was unaware of vcs_info)
-
ntc2 about 11 years@balki The
%F{n}
enable ANSI colorn
for foreground, and%f
disables foreground color. E.g., theformats
format%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{3}]%f
becomes(%s)-[%b]
if you ignore the colors. The%s
gets replaced by the vc system (e.g. git) and the%b
gets replaced by the current branch. -
ntc2 about 11 years@balki The
(sv[nk]|bzr)
subpattern on thebranchformat
restricts it tosvn
,svk
, andbzr
. It means that those systems should usebranch:revision
instead of the defaultbranch
. Because of theenable
line,bzr
is not supported, so thisbzr
restriction is "dead code". The first three lines are copied verbatim from the ZSH docs, but the last line was added by someone else, which probably explains the dead code. -
ntc2 about 11 years@balki The
actionformats
becomes(%s)-[%b|%a]
ignoring colors. This format is used during special actions, with%a
describing the action. This is the most useful feature IMHO: e.g. for git it tells when you are in the middle of a rebase (which I often forget about while trying to resolve merge conflicts). -
Thanatos over 10 years@Jakub Narębski: You can also do
git symbolic-ref --short HEAD
, which will remove the "refs/heads/" business for you. -
Thomas Upton almost 10 yearsThis is a great git-specific use of
vcs_info
. One thing though:git status
is slow. I usedgit ls-files --other --directory --exclude-standard | sed q | wc -l | tr -d ' '
instead, and it's much faster. -
Christopher almost 10 yearsNice modification. Updated accordingly.
-
Thomas Upton almost 10 yearsThe
--directory
flag might not actually be necessary. I found that it was annoying because git usually ignores empty directories. -
szeryf over 9 yearsHad the same problem (i.e. empty directories ignored by git caused
??
to appear in the prompt). Fixed by adding--no-empty-directory
flag to thegit ls-files
command. -
David Faure over 9 yearsI've been using this for a long time, and it always worked well. Now however, after updating to zsh 5.0.7 and git 1.8.4, I get "fatal: Not a git repository" whenever going into a directory that is not a git repo. Any suggestions? (I see many discussions on detecting whether or not we're in a git repo, but I don't want to exit early if not, I also have svn repos... vcs_info was great at encapsulating all that...)
-
David Faure over 9 yearsAh, found a solution: replacing the call to vcs_info with vcs_info 2>/dev/null
-
Timofey almost 9 yearshaving trouble during sourcing: " unrecognized modifier `A'". zsh 4.2.6 (x86_64-redhat-linux-gnu). Is it a known issue?
-
ssokolow over 4 years
git symbolic-ref --short HEAD 2> /dev/null
will get you an answer that requires less parsing. -
Ev0oD over 3 yearsRepository no longer maintained - seems like some guys took over here: github.com/zsh-git-prompt/zsh-git-prompt editing answer to link to it
-
Ev0oD over 3 yearsCouldn't make it run neither with the repo I mention above. Found out ohmyzsh does it nicely, see stackoverflow.com/a/63919265/1920149
-
alper almost 3 yearslink for
git prompt
seems dead :( -
SwiftMango over 2 yearsIn the first simple solution, also use
cut -d'/' -f3-
, it will make sure to include the full name of the branch, if the branch name is likefeature/xyz
-
Manish over 2 yearsWhere to add this code?
-
Maria Ines Parnisari over 2 years@Manish in your ~/.zshrc file
-
Weston Ganger almost 2 yearsPlease note that the PROMPT must be in single quotes for the command to be re-run whenever changing directories
-
Weston Ganger almost 2 yearsPlease note that the PROMPT must be in single quotes for the command to be re-run whenever changing directories
-
Weston Ganger almost 2 yearsThank you so much for this tip about single quotes. My desire to use double quotes bit me here.
-
Dan Rosenstark almost 2 yearsLike it is @WestonGanger or you're suggesting something else?