git - 将 parse_git_branch 函数从 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 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 的变化而中断(它们不会改变管道)。这对于一个好的脚本向前发展非常重要。

最佳答案

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

使用陶瓷接口(interface),也可以在没有“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 特定的(即转义或引用 $(对于 bashzsh)并设置PROMPT_SUBST(用于 zsh))。

关于git - 将 parse_git_branch 函数从 bash 翻译成 zsh(用于提示),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2850425/

相关文章:

git - 在我 pull 后,有人从远程存储库中删除了提交,如何在下一次 git pull 时将其保留在本地?

git - Webpack 和更改 git 中的分支 - 永无休止的冲突

linux - 脚本无法获取 "Not Valid Identifier"

c - 通过 shell 命令获取 C 应用程序的参数

ZSH "command not found: z"

macos - MacOS 上 zsh 终端中的穿梭 : "expected server init string b' SSHUTTLE000 1'; got b' '"

git - 在 Git 中恢复文件的修改时间

git - 如何确保提交作者

bash 脚本 : started with $! 而不是#!并得到了神秘的行为。发生了什么?

git - ZSH 提示未显示 git unstaged 文件