Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将parse_git_分支函数从bash转换为zsh(用于提示)_Git_Bash_Zsh - Fatal编程技术网

将parse_git_分支函数从bash转换为zsh(用于提示)

将parse_git_分支函数从bash转换为zsh(用于提示),git,bash,zsh,Git,Bash,Zsh,我在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

我在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}

我需要做些什么来准备下地狱

Edit:我得到的“实际错误”是
“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状态
是瓷器(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\u git\u branch)”


这可能会慢一些(更多地调用GIT,但这是一个经验问题),但它不会被GIT中的更改打破(它们不会改变管道)。这对于一个好的脚本向前发展非常重要。

摆脱多余的
}
${GIT\u status}
应该是
${GIT\u status}


一旦额外的
}
被删除,我看到的唯一潜在问题就是
${BASH_REMATCH[1]}
的使用。您可以在zsh中使用它,但它需要启用该选项来执行此操作

if [[ ${git_status} =~ ${pattern} ]]; then
  branch=${match[1]}
  echo "(${branch}${state})"
fi
可能这将包含一些测试,可以为您提供一些线索:


如果您不想学习zsh,我建议您使用另一种语言,如Python,进行这种解析


查看github上的和,查看如何为git获得一个漂亮的
zsh
提示。

如果编译正则表达式时出现错误
失败:非法字节序列
,则从IFS中删除NULL。(将
${IFS}
替换为
${IFS/$'\0'/}
).

您可以使用数组
匹配
而不是
$BASH\u 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
}

试试看它是否有用。

你真的应该使用Git“管道”命令来提取你想要的信息。“瓷器”命令的输出(例如,
Git status
)可能会随着时间的推移而改变,但“管道”命令的行为要稳定得多

使用瓷接口,也可以在没有“bashisms”或“zshisms”(即
=~
匹配运算符)的情况下完成:

parse_git_branch(){
在_wd=“$(git rev parse--is in work tree 2>/dev/null)”中返回
测试“$in_wd”=true|返回
状态=“”
git更新索引--refresh-q>/dev/null#使用diff索引避免误报
如果git rev parse——验证HEAD>/dev/null 2>&1;则
git diff索引头--quiet 2>/dev/null | | state='*'
其他的
状态='#'
fi
(
d=“$(git rev parse--show cdup)”&&
cd“$d”&&
test-z“$(git ls文件--其他--排除标准)
)>/dev/null 2>&1 | | state=“${state}+”
branch=“$(git符号参考头2>/dev/null)”
测试-z“$branch”和&branch=''
echo“${branch#refs/heads/}${state}”
}

将输出集成到提示符中仍然是特定于shell的(即,转义或引用
$
(对于bash和zsh),并设置提示符\u SUBST(对于zsh)).

为了防止任何人有兴趣看到git提示符功能的替代解决方案,我已经在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\] '

已经尝试过了,那么它就变成了同一行上的一个不同的错误。基本上这将需要一个知道ZSH,Maynkes的人。谢谢你想,为什么不更新你的问题来消除那个明显的错误,并公布你得到的实际错误?这并不意味着它不是一个错误。这仅仅意味着BASH对它的PAR没有严格要求。sing.Bash将
${git_status}}
视为
“无论什么{git_status}扩展到}”
,而Zsh将
${git_status}
视为解析错误,因为您有一个游离的
}
。如果希望它们相同,请将
${git_status}
放在引号中--
“${git_status}”“
。那么我想知道您实际将
$IFS
设置为什么。默认值
\x20\t\n\x00
,对我来说很好。或者,您可以使用
[^[:space:]
而不是
[^${IFS}]
。一如既往地感谢VonC。如果可能的话,我正在寻找一种简单的解决方法,但我们会看看这个问题的进展。关键是它必须是一个内联函数。正如我在问题中所说,作为一个
sh
脚本,它运行得很好。虽然我可以在Ruby中再次这样做,但这不会加快加载速度,这就是重点。虽然我已经使用了在zsh git prompt项目中,似乎它不会在每次点击return时都进行解析…?是的,它会在每次点击return时进行解析。好的,我会检查一下,它比当前的脚本(上面)有一些明显的优势。一个带有
\0
$IFS
在我正在使用的zsh上运行得很好--4.3.10。虽然你的答案基本上解决了我的问题,但是jamessan整天都在和我一起工作:)感谢你们两位的帮助。zsh 4.3.4还添加了
[:IFSSPACE:
。很酷,代码中可能会更好。我会检查一下(在某种程度上,这会分散人们对实际工作的注意力)。再次感谢您的耐心和帮助。感谢Dennis,现在一切都很好,match确实按照jamessan在其一个修订版中的建议工作了。在我看来,像这样使用IFS是没有意义的。IFS用于解析shell输入。来自
git status
的输出永远不会依赖于IFS。您应该使用您期望的

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\] '