To get a prompt which indicates Git-branch in Zsh

前端 未结 9 1857
滥情空心
滥情空心 2020-12-04 09:12

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.

相关标签:
9条回答
  • 2020-12-04 09:34

    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:

    prompt

    Compared with git status -s:

    enter image description here

    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.

    0 讨论(0)
  • 2020-12-04 09:35

    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.

    0 讨论(0)
  • 2020-12-04 09:36

    This already has a many great answers, and seems like the authoritative Question for readers who don't want to use more than the zsh config and git.

    However, I found myself wanting simply

    working-directory (git-branch-color-if-uncommitted) %          24h-timestamp
    
    git_branch_test_color() {
      local ref=$(git symbolic-ref --short HEAD 2> /dev/null)
      if [ -n "${ref}" ]; then
        if [ -n "$(git status --porcelain)" ]; then
          local gitstatuscolor='%F{red}'
        else
          local gitstatuscolor='%F{green}'
        fi
        echo "${gitstatuscolor} (${ref})"
      else
        echo ""
      fi
    }
    setopt PROMPT_SUBST
    PROMPT='%9c$(git_branch_test_color)%F{none} %# '
    
    # add 24h time the right side
    RPROMPT='%D{%k:%M:%S}'
    

    This works by

    • allowing inclusion of a function ($()) by setting PROMPT_SUBST (thanks to Phil's 2017 answer!)
    • declaring a function git_branch_test_color to call git for the branch ref ..and by whether this succeeds (tests for stdout) if the current directory is a git repository
      (thanks to a few comments for symbolic-ref arg!)
      • if not a git repo, only echo an empty string ""
    • if the initial call did succeed (does have collected stdout), the current directory is a git directory and
      git status --porcelain is used to determine if any files have been changed or are new/deleted
      • green coloration prefix for unchanged
      • red coloration prefix for changes (whatever they may be)

    Note that all such prompts can be slow on mounted directories (especially via sshfs). If this is experienced, I recommend special-casing those directories if at all possible (perhaps create a new shell function to check if cd is in your collection) or always mount in the same path and ignore it (example with vcs_info)

    0 讨论(0)
  • 2020-12-04 09:38

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

    alt text

    0 讨论(0)
  • 2020-12-04 09:38

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

    0 讨论(0)
  • 2020-12-04 09:42

    For anyone interested in a maintained ready-made solution, install https://github.com/ohmyzsh/ohmyzsh - it has a git plugin turned on by default. I was looking for sth like this - no-brainer pre-created configuration, works nice.

    0 讨论(0)
提交回复
热议问题