To get a prompt which indicates Git-branch in Zsh

时光毁灭记忆、已成空白 提交于 2019-11-28 16:11:14

__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)' 

Here is an extended git prompt for zsh: zsh-git-prompt.

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.

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) $

Thank you for the links!

I made the following prompt based on them

     # get the name of the branch we are on      git_prompt_info() {           git branch | awk '/^\*/ { print $2 }'      }      get_git_dirty() {         git diff --quiet || echo '*'      }       autoload -U colors      colors           setopt prompt_subst       PROMPT='%{$fg[blue]%}%c %{$fg_bold[red]%}$(git_prompt_info)$(get_git_dirty)%{$fg[blue]%} $ %{$reset_color%}'                                                  RPROMPT='%{$fg[green]%}%1(j.%j.)'         

Please, suggest any improvements.

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.)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!