我在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
}
但我决定使用zsh。虽然我可以在我的.zshrc中完美地使用它作为shell脚本(即使没有shebang),但错误是此行if [[ ! ${git_status}}
上的解析错误...
我需要做些什么才能为zshell做好准备?
编辑:我收到的“实际错误”是" parse error near }
,它指的是带有奇怪的双}}
的行,它适用于Bash。
编辑:这是最终的代码,只是为了好玩:
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'
感谢大家的耐心和帮助。
编辑:最好的答案是我们所有人:git status
是瓷器(UI)。好的脚本与GIT管道相悖。这是最后的功能:
# 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'
请注意,只有提示符是特定于zsh的。在Bash中,它将是您的提示加"\$(parse_git_branch)"
。
这可能会更慢(对GIT的更多调用,但这是一个经验问题)但它不会被GIT中的更改打破(它们不会改变管道)。这对于一个好的剧本来说非常重要。
答案 0 :(得分:5)
你应该使用Git“plumbing”命令来提取你想要的信息。 “瓷器”命令(例如git status
)的输出可能会随着时间的推移而改变,但“管道”命令的行为会更加稳定。
使用瓷器接口,也可以在没有“bashisms”或“zshisms”的情况下完成(即=~
匹配运算符):
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}"
}
将输出集成到提示符中仍然是特定于shell的(即转义或引用$
(对于 bash 和 zsh )并设置PROMPT_SUBST(对于的zsh ))。
答案 1 :(得分:2)
摆脱额外的}
? ${git_status}}
应为${git_status}
。
删除额外}
后,我看到的唯一潜在问题是使用${BASH_REMATCH[1]}
。您可以在zsh中使用它,但它需要启用该选项才能执行此操作。正如conditional expressions上的zsh文档所示,您需要使用类似
if [[ ${git_status} =~ ${pattern} ]]; then
branch=${match[1]}
echo "(${branch}${state})"
fi
答案 2 :(得分:2)
您可以使用数组match
代替$BASH_REMATCH
。你也可以逃脱额外的大括号。
未测试:
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
}
尝试一下,看看它是否有帮助。
答案 3 :(得分:1)
如果你不想学习zsh,我建议你使用另一种语言,比如Python,进行那种解析。
查看github上的git status Python parser和zsh-git-prompt project,了解如何获得git的zsh
提示。
答案 4 :(得分:1)
如果收到错误failed to compile regex: illegal byte sequence
,则从IFS中删除NULL。 (将${IFS}
替换为${IFS//$'\0'/}
)。
答案 5 :(得分:0)
可能这个zsh Git repository将包含可以给你一些线索的测试:
答案 6 :(得分:0)
如果有人有兴趣看到git-prompt功能的替代解决方案,我已经在github.com上发布了这个脚本,但是为了更容易,你可以从这里获得它。
它对我很有用,希望它对你也一样。
## 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;
}
用法:
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\] '