Um eine Eingabeaufforderung zu erhalten, die Git-branch in Zsh anzeigt

73

Ich führe die folgenden Codes separat als meine Eingabeaufforderung in .zshrc erfolglos aus. Dies deutet darauf hin, dass ich anscheinend kein Programm namens __git_ps1 habe. Es ist nicht 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%}'

Wie kann man eine Eingabeaufforderung erhalten, die den Namen eines Git-Zweigs anzeigt?

Léo Léopold Hertz 준영
quelle

Antworten:

77

__git_ps1ist von git-vervollständigung.bash. In zsh müssen Sie wahrscheinlich Ihre eigene Funktion bereitstellen, um den aktuellen Verzeichnis-Git-Zweig zu bestimmen. Es gibt einige Blog-Beiträge über eine Git-Eingabeaufforderung für zsh.

Du brauchst nur:

  • eine Funktion zur Angabe des Filialnamens
  • Aktivieren Sie die Eingabeaufforderung (Befehl)
  • Fügen Sie die Funktion Ihrer Eingabeaufforderung hinzu

Zum Beispiel

git_prompt() {
 ref=$(git symbolic-ref HEAD | cut -d'/' -f3)
 echo $ref
}
setopt prompt_subst
PS1=$(git_prompt)%#
autoload -U promptinit
promptinit

Update: Verwenden Sie das Modul zsh vcs_info anstelle von 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)'
ko-dos
quelle
5
git_prompt ist falsch, wenn Sie einen Zweig mit / haben, der nicht funktioniert. Verwenden Sie cut -d'/' -f3-stattdessen.
Drizzt
1
Danke!, Das funktioniert. Können Sie bitte erklären, was diese kryptischen zstyle-Befehle bewirken?
Balki
1
@balki %F{n}Aktiviert die ANSI-Farbe n für den Vordergrund und %fdeaktiviert die Vordergrundfarbe. Das formatsFormat %F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{3}]%f wird beispielsweise, (%s)-[%b]wenn Sie die Farben ignorieren. Das %swird durch das VC-System (zB Git) ersetzt und das %bwird durch den aktuellen Zweig ersetzt.
Ntc2
1
@balki Die (sv[nk]|bzr)Unter - Pattern auf den branchformatengt es zu svn, svkund bzr. Dies bedeutet, dass diese Systeme branch:revisionanstelle der Standardeinstellung verwendet werden sollten branch. Wegen der enableZeile bzrwird nicht unterstützt, daher ist diese bzrEinschränkung "toter Code". Die ersten drei Zeilen werden wörtlich aus den ZSH-Dokumenten kopiert , aber die letzte Zeile wurde von jemand anderem hinzugefügt, was wahrscheinlich den toten Code erklärt.
Ntc2
1
@balki Das actionformatswird (%s)-[%b|%a]Farben ignorieren. Dieses Format wird bei speziellen Aktionen verwendet, wobei %adie Aktion beschrieben wird. Dies ist meiner Meinung nach die nützlichste Funktion: zB für git wird angezeigt, wann Sie sich mitten in einer Rebase befinden (was ich beim Versuch, Zusammenführungskonflikte zu lösen, oft vergesse).
Ntc2
41

Hier ist eine erweiterte Git-Eingabeaufforderung für zsh: zsh-git-prompt .

Alt-Text

Olivier Verdier
quelle
1
Liebe es! Perfekt. Sehr gute Arbeit und jetzt ein Submodul in meinem eigenen Dotfiles-Repo. :)
Justin Force
2
Wie ist Ihr Ansatz im Vergleich zu vcs_info? Es scheint, dass Ihr Skript das Rad neu erfindet? (Hat mich aber nicht davon abgehalten, es zu benutzen, ich wusste nichts von vcs_info)
Schaden
Probleme beim Sourcing: "nicht erkannter Modifikator" A "". zsh 4.2.6 (x86_64-redhat-linux-gnu). Ist es ein bekanntes Problem?
Timofey
Repository nicht mehr gepflegt - anscheinend haben einige Leute hier übernommen: github.com/zsh-git-prompt/zsh-git-prompt Antwort auf den Link bearbeiten
Ev0oD
38

Die Antwort von ko-dos ist großartig, aber ich bevorzuge eine etwas git-bewusstere Eingabeaufforderung als die, die er verwendet. Insbesondere mag ich Benachrichtigungen über bereitgestellte, nicht bereitgestellte und nicht verfolgte Dateien in der Eingabeaufforderung. Anhand seiner Antwort und der zsh vcs_info-Beispiele habe ich Folgendes gefunden:

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%# '

Dadurch wird eine Eingabeaufforderung erstellt, die die kolorierte Ausgabe von git status -s(die in Ihrer .gitconfigDatei konfiguriert werden kann) nachahmt . Ein Bild ist hier vielleicht am hilfreichsten:

prompt

Verglichen mit git status -s:

Geben Sie hier die Bildbeschreibung ein

Wenn Sie nicht wie kolorierte Ausgabe, oder würde ein anderes Zeichen oder die schnelle Konstruktion bevorzugen, ändern Sie einfach die stagedstr, unstagedstrund hook_com[unstaged]Werte in dem obigen Code.

Christopher
quelle
1
Dies ist eine großartige git-spezifische Verwendung von vcs_info. Eines ist jedoch: git statusist langsam . Ich habe git ls-files --other --directory --exclude-standard | sed q | wc -l | tr -d ' 'stattdessen verwendet, und es ist viel schneller.
Thomas Upton
Schöne Modifikation. Entsprechend aktualisiert.
Christopher
Die --directoryFlagge ist möglicherweise nicht erforderlich. Ich fand es ärgerlich, weil Git normalerweise leere Verzeichnisse ignoriert.
Thomas Upton
Hatte das gleiche Problem (dh leere Verzeichnisse, die von git ignoriert wurden ??und in der Eingabeaufforderung angezeigt wurden). Behoben durch Hinzufügen eines --no-empty-directoryFlags zum git ls-filesBefehl.
Szeryf
30

Viele dieser Lösungen schienen mir beim Drücken der Eingabetaste langsam zu sein. Hier ist eine Option, die einfach und schnell ist:

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}%} $ '

Sie erhalten eine Eingabeaufforderung, die folgendermaßen aussieht: ~/dev/project (feature-branch) $

Phil
quelle
4
git symbolic-ref --short HEAD 2> /dev/nullSie erhalten eine Antwort, die weniger Analyse erfordert.
Ssokolow
8

Ich habe gerade meine überarbeitet, da wir lange Filialnamen bei der Arbeit haben. Dieser wird mit einem Auslassungszeichen abgeschnitten, wenn er mehr als 35 Zeichen umfasst.

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

(Es ist mir peinlich, wie stolz ich darauf bin.)

Dan Rosenstark
quelle
0

Danke für die Links!

Ich habe die folgende Eingabeaufforderung basierend auf ihnen gemacht

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

Bitte schlagen Sie Verbesserungen vor.

Léo Léopold Hertz 준영
quelle
3
Verwenden Sie keinen Git-Zweig. Es ist Porzellan, das für die Benutzeroberfläche gedacht ist, nicht für Skripte. Verwenden Sie git-symbolic-ref und BR = $ {BR # refs / Heads /}
Jakub Narębski
@ Jakub: Danke, dass du darauf hingewiesen hast! --- Ich habe gerade beobachtet, dass Git-Branch Fehler mit Nicht-Git-Verzeichnissen verursacht.
Léo Léopold Hertz 준영
4
@Jakub Narębski: Sie können auch das tun git symbolic-ref --short HEAD, wodurch das Geschäft "refs / Heads /" für Sie entfernt wird.
Thanatos
0

Für alle, die an einer vorgefertigten Lösung interessiert sind, installieren Sie https://github.com/ohmyzsh/ohmyzsh - standardmäßig ist ein Git-Plugin aktiviert. Ich habe nach so etwas gesucht - einfache, vorgefertigte Konfiguration, funktioniert gut.

Ev0oD
quelle
0

Wenn alle Ihre Eingabeaufforderungen gut aussehen, aber nicht funktionieren, z.

function git_branch(){                                                                                                                 
    ref=$(git symbolic-ref --short --quiet HEAD 2>/dev/null)        
    if [ -n "${ref}" ]; then                                                    
        echo "(""$ref"")"                                                       
    fi                                                                          
}                                                                               
                                                                                
setopt PROMPT_SUBST                                                             

PROMPT="%{$fg[red]%}%n%{$reset_color%}@%{$fg[blue]%}%m:%{$fg[yellow]%}%1~%{$reset_color%} %{%F{green}%}$(git_branch)%{%F{none}%}$ "

Das PROMPT muss auf eine Zeichenfolge gesetzt werden, die in einfache Anführungszeichen anstatt in doppelte Anführungszeichen gesetzt wird.

PROMPT='%{$fg[red]%}%n%{$reset_color%}@%{$fg[blue]%}%m:%{$fg[yellow]%}%1~%{$reset_color%} %{%F{green}%}$(git_branch)%{%F{none}%}$ '
HVNSweeting
quelle