Py学习  »  Git

从bash将parse git_分支函数转换为zsh(提示)

Sam Coles • 5 年前 • 747 次点击  

我在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的变化破坏(它们不会改变管道)。这对于一个好的剧本来说是非常重要的。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/31492
 
747 次点击  
文章 [ 7 ]  |  最新文章 5 年前
tocororo
Reply   •   1 楼
tocororo    12 年前

为了防止任何人有兴趣看到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\] '
VonC
Reply   •   2 楼
VonC    13 年前

可能是这样 zsh Git repository 将包含一些可以给您一些提示的测试:

ZyX
Reply   •   3 楼
ZyX    13 年前

如果你出错了 failed to compile regex: illegal byte sequence 然后从ifs中删除空值。(替换) ${IFS} 具有 ${IFS//$'\0'/} )

Olivier Verdier
Reply   •   4 楼
Olivier Verdier    13 年前

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

退房 git status Python parser 以及 zsh-git-prompt project 在Github上看看如何得到一个 zsh 提示Git。

Dennis Williamson
Reply   •   5 楼
Dennis Williamson    13 年前

你可以使用数组 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
}

试一试,看看是否有帮助。

jamessan
Reply   •   6 楼
jamessan    13 年前

去掉多余的 } ? ${git_status}} 应该是 ${git_status} .


一旦额外 } 被移除,我看到的唯一潜在问题是 ${BASH_REMATCH[1]} . 您可以在zsh中使用它,但它需要启用选项才能这样做。作为ZSH文档 conditional expressions 显示,您需要使用

if [[ ${git_status} =~ ${pattern} ]]; then
  branch=${match[1]}
  echo "(${branch}${state})"
fi
Chris Johnsen
Reply   •   7 楼
Chris Johnsen    13 年前

你真的应该使用git_156;pluging_157;命令来提取你想要的信息。__瓷_命令的输出(例如 git status )可能会随时间变化,但__pitting_命令的行为更稳定。

有了瓷质界面,也可以不用__bashisms_157;或_156;zshisms_157;(即 =~ 匹配运算符):

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特有的(即,转义或引用 $ (两者兼而有之) 猛击 ZSH )并设置提示 ZSH )