Translate parse_git_branch function to zsh from bash (for prompt)
- by yar
I am using this function in 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
}
but I'm determined to use zsh. While I can use this perfectly as a shell script (even without a shebang) in my .zshrc the error is a parse error on this line if [[ ! ${git_status}}...
What do I need to do to get it ready for zshell?
Edit: The "actual error" I'm getting is " parse error near } and it refers to the line with the strange double }}, which works on Bash.
Edit: Here's the final code, just for fun:
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'
Thanks to everybody for your patience and help.
Edit: The best answer has schooled us all: git status is porcelain (UI). Good scripting goes against GIT plumbing. Here's the final function:
parse_git_branch() {
in_wd="$(git rev-parse --is-inside-work-tree 2>/dev/null)" || return
test "$in_wd" = true || return
state=''
git diff-index HEAD --quiet 2>/dev/null || state='*'
branch="$(git symbolic-ref HEAD 2>/dev/null)"
test -z "$branch" && branch='<detached-HEAD>'
echo "(${branch#refs/heads/}${state})"
}
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'
Note that only the prompt is zsh-specific. In Bash it would be your prompt plus "\$(parse_git_branch)".
This might be slower (more calls to GIT, but that's an empirical question) but it won't be broken by changes in GIT (they don't change the plumbing). And that is very important for a good script moving forward.
Days Later: Ugh, it turns out that diff-index HEAD is NOT the same as checking status against working directory clean. So will this mean another plumbing call? I surely don't have time/expertise to write my own porcelain....