Traduzca la function parse_git_branch a zsh desde bash (por aviso)

Estoy usando esta function en Bash

function parse_git_branch { git_status="$(git status 2> /dev/null)" pattern="^# On branch ([^${IFS}]*)" if [[ ! ${git_status}} =~ "working directory clean" ]]; then state="*" fi # add an else if or two here if you want to get more specific if [[ ${git_status} =~ ${pattern} ]]; then branch=${BASH_REMATCH[1]} echo "(${branch}${state})" fi } 

pero estoy decidido a usar zsh. Si bien puedo usar esto perfectamente como script de shell (incluso sin shebang) en mi .zshrc, el error es un error de análisis en esta línea if [[ ! ${git_status}} if [[ ! ${git_status}}

¿Qué debo hacer para prepararlo para zshell?

Editar: El "error real" que obtengo es " parse error near } y se refiere a la línea con el doble extraño }} , que funciona en Bash.

Editar: Aquí está el código final, solo por diversión:

 parse_git_branch() { git_status="$(git status 2> /dev/null)" pattern="^# On branch ([^[:space:]]*)" if [[ ! ${git_status} =~ "working directory clean" ]]; then state="*" fi if [[ ${git_status} =~ ${pattern} ]]; then branch=${match[1]} echo "(${branch}${state})" fi } setopt PROMPT_SUBST PROMPT='$PR_GREEN%n@$PR_GREEN%m%u$PR_NO_COLOR:$PR_BLUE%2c$PR_NO_COLOR%(!.#.$)' RPROMPT='$PR_GREEN$(parse_git_branch)$PR_NO_COLOR' 

Gracias a todos por su paciencia y ayuda.

Editar: La mejor respuesta nos ha enseñado a todos: el git status es porcelana (UI). Las buenas secuencias de commands van en contra de la tubería de GIT. Aquí está la function final:

 # The latest version of Chris' function below PROMPT='$PR_GREEN%n@$PR_GREEN%m%u$PR_NO_COLOR:$PR_BLUE%2c$PR_NO_COLOR%(!.#.$)' RPROMPT='$PR_GREEN$(parse_git_branch)$PR_NO_COLOR' 

Tenga en count que solo el post es específico de zsh. En Bash sería su prompt más "\$(parse_git_branch)" .

Esto podría ser más lento (más llamadas a GIT, pero esa es una pregunta empírica) pero no se romperá por los cambios en GIT (no cambian las tuberías). Y eso es muy importante para que un buen guión avance.

Realmente debería usar los commands de "fontanería" de Git para extraer la información que desea. La salida de los commands de "porcelana" (por ejemplo, git status ) puede cambiar con el time, pero el comportamiento de los commands de "fontanería" es mucho más estable.

Con las interfaces de porcelana, también se puede hacer sin "bashisms" o "zshisms" (es decir, el operador =~ matching):

 parse_git_branch() { in_wd="$(git rev-parse --is-inside-work-tree 2>/dev/null)" || return test "$in_wd" = true || return state='' git update-index --refresh -q >/dev/null # avoid false positives with diff-index if git rev-parse --verify HEAD >/dev/null 2>&1; then git diff-index HEAD --quiet 2>/dev/null || state='*' else state='#' fi ( d="$(git rev-parse --show-cdup)" && cd "$d" && test -z "$(git ls-files --others --exclude-standard .)" ) >/dev/null 2>&1 || state="${state}+" branch="$(git symbolic-ref HEAD 2>/dev/null)" test -z "$branch" && branch='<detached-HEAD>' echo "${branch#refs/heads/}${state}" } 

La integración de la salida en el prompt aún es específica del shell (es decir, escape o cite el $ (para ambos bash y zsh ) y configure PROMPT_SUBST (para zsh )).

Deshazte del extra } ? ${git_status}} debería ser ${git_status} .


Una vez que se elimina el extra } , el único problema potencial que veo es el uso de ${BASH_REMATCH[1]} . Puede usar eso en zsh, pero requiere habilitar la opción para hacerlo. Como muestran los documentos zsh en expresiones condicionales , necesitarías usar algo como

 if [[ ${git_status} =~ ${pattern} ]]; then branch=${match[1]} echo "(${branch}${state})" fi 

Puede usar la match matriz en lugar de $BASH_REMATCH . También puede escaping de la llave de cierre adicional.

No probado:

 function parse_git_branch { git_status="$(git status 2> /dev/null)" pattern="^# On branch ([^${IFS}]*)" if [[ ! ${git_status}\} =~ "working directory clean" ]]; then state="*" fi # add an else if or two here if you want to get more specific if [[ ${git_status} =~ ${pattern} ]]; then branch=${match[1]} echo "(${branch}${state})" fi } 

Pruébalo y ve si ayuda.

Si no quiere aprender zsh, le sugiero que use otro idioma, como Python, para ese tipo de análisis.

Consulte el analizador de Python de estado de git y el proyecto zsh-git-prompt en github para ver cómo get un buen indicador de zsh para git.

Si obtiene un error failed to compile regex: illegal byte sequence , elimine NULL de IFS. (Reemplazar ${IFS} con ${IFS//$'\0'/} ).

Puede ser que este repository de zsh Git contenga testings que pueden darle alguna pista:

  • A01grammar.ztst
  • A07control.ztst

En caso de que alguien esté interesado en ver una solución alternativa a la funcionalidad de git-prompt, he publicado este script en github.com, pero para hacerlo más fácil, puede getlo desde aquí.

Funciona muy bien para mí, espero que te haga lo mismo.

 ## Setting Prompt Colour(s): invColor="$(tput rev)"; ## tput rev - Inverse resColor="$(tput sgr0)"; ## tput sgr0 - Reset ## Custom Prompt Colour(s): _BlackBG="$(tput setab 0)"; bGreenFG="$(tput bold; tput setaf 2)"; bMagentaFG="$(tout bold; tput setaf 5)"; bRedFG="$(tput bold; tput setaf 1)"; bBlueFG="$(tput bold; tput setaf 4)"; bCyanFG="$(tput bold; tput setaf 6)"; bWhiteFG="$(tput bold; tput setaf 7)"; ## Define Enclosing-character(s): _Bracket="${resColor}${_BlackBG}${bWhiteFG}"; oBracket="${_Bracket}["; cBracket="${_Bracket}]${resColor}"; ## Bold-Foreground Color(s): ## tput bold - Bold function git_branch () { # git_branch() { git name-rev HEAD 2> /dev/null | sed 's#HEAD\ \(.*\)#git::\1#'; } git branch --no-color 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/git::\1/'; return 0; } ## Version Control System - Active Working Copy: function get_branch () { xBranch="`git_branch`"; if [[ "${xBranch}" =~ "git::master" ]]; then xBranch="git::${bWhiteFG}master"; else xBranch="`echo ${xBranch}|sed -e 's/git:://g'`"; xBranch="branch::${bGreenFG}${xBranch}"; fi if git rev-parse --git-dir >/dev/null 2>&1; then _pVCS=""; if git diff --quiet 2>/dev/null >&2; then if [[ "${xBranch}" =~ "git::" ]]; then _pVCS="${bGreenFG}${xBranch}"; else _pVCS="${bMagentaFG}${xBranch}"; fi else _pVCS="${bRedFG}${xBranch}"; fi else return 0; fi if [[ "${_pVCS}" =~ "no branch" ]]; then xTAG="`git tags|awk '{print $3}'|sed -e 's/[,;)]//g'`"; _pVCS="${bBlueFG}tag::${bCyanFG}${xTAG}"; fi ## Output Git Active-Repo ID: if [[ "${_pVCS}" =~ [::] ]]; then echo -ne "${oBracket}${_BlackBG}${_pVCS}${cBracket}"; fi # return 0; } 

Uso:

 declare PS1='\[\033[01;36m\]\u\[\033[01;31m\]@\[\033[01;32m\]\h\[\033[00m\]:\[\033[01;33m\]\w $(get_branch) \[\033[01;31m\]${XPT}\[\033[00m\] '