git - 在 bash 提示符下为 git status 设置颜色

标签 git bash command-prompt prompt

我正在尝试使用以下脚本将我的 bash 提示符设置为。一切正常,但我打印出 Git 存储库中的分支名称和彩色分支状态的部分。颜色有些随意,但不用说,如果有任何文件未提交,则颜色为红色,如果文件未暂存,则颜色为黄色,其他颜色为绿色。它正在用白色思想打印出我想要的部分。当我运行脚本的一部分时,在最后,我单独定义了 $branchStyle,它可以工作,但它不在此处。我做错了什么?

prompt_git() {
  local s=""
  local branchName=""

  # check if the current directory is in a git repository
  if [ $(git rev-parse --is-inside-work-tree &>/dev/null; printf "%s" $?) == 0 ]; then

      # check if the current directory is in .git before running git checks
      if [ "$(git rev-parse --is-inside-git-dir 2> /dev/null)" == "false" ]; then

          # ensure index is up to date
          git update-index --really-refresh  -q &>/dev/null

          # check for uncommitted changes in the index
          if ! $(git diff --quiet --ignore-submodules --cached); then
              s="$s+";
          fi

          # check for unstaged changes
          if ! $(git diff-files --quiet --ignore-submodules --); then
              s="$s!";
          fi

          # check for untracked files
          if [ -n "$(git ls-files --others --exclude-standard)" ]; then
              s="$s?";
          fi

          # check for stashed files
          if $(git rev-parse --verify refs/stash &>/dev/null); then
              s="$s$";
          fi

      fi

      # get the short symbolic ref
      # if HEAD isn't a symbolic ref, get the short SHA
      # otherwise, just give up
      branchName="$(git symbolic-ref --quiet --short HEAD 2> /dev/null || \
                  git rev-parse --short HEAD 2> /dev/null || \
                  printf "(unknown)")"

      [ -n "$s" ] && s=" [$s]"

      printf "%s" "$1$branchName$s"
  else
      return
  fi
}

set_prompts() {

    local bold=$(tput bold)
    local reset=$(tput sgr0)
    local base05=$(tput setaf 188) # light grey
    local base08=$(tput setaf 210) # red
    local base0A=$(tput setaf 221) # yellow
    local base0B=$(tput setaf 114) # green

    if git rev-parse --git-dir >/dev/null 2>&1; then
        # check for uncommitted changes in the index
        if ! git diff-index --quiet --cached HEAD --ignore-submodules -- >&2; then
            branchStyle=$base08
        # check for unstaged changes
        elif ! git diff-files --quiet --ignore-submodules -- >&2; then
            branchStyle=$base0A
        else
            branchStyle=$base0B
        fi
    fi

    PS1+="\$(prompt_git \"$bold$base05 on $branchStyle\")" # git repository details

    export PS1
}

set_prompts
unset set_prompts

最佳答案

解决任何问题的一个好方法是将其减少到重现您所看到的问题所需的最少代码段。这使得调试更容易,其他人更容易阅读和解决问题,并提出其他用户可以从中受益的更普遍的问题。

例如,如果您查看您的问题,您会发现:

  • 它与 prompt_git 函数无关:用简单的 echo 替换它时会发生同样的事情。
  • 它与颜色无关:如果您使用纯字符串,也会发生同样的事情。
  • 它与未暂存或未提交的文件无关:如果您跳过这些检查,也会发生同样的事情。
  • 它与 git 完全无关:如果你只是比较目录,同样的事情也会发生。

现在我们可以用一个小代码示例编写一个问题来准确显示问题所在:

I expected the following piece of code to show "in /tmp" when I cd /tmp, but instead the prompt remains blank. Why doesn't it update?

set_prompts() { 
  message=""
  if [[ $PWD/ == /tmp/* ]]
  then
    message="in /tmp"
  fi
  PS1="\$(echo $message) \$"
}
set_prompts
unset set_prompts

这个问题更容易阅读和回答:set_prompts 运行一次并为 $message 计算一个值,然后它被取消设置并且不再执行。这就是消息永远不会改变的原因。

要使其正常工作,请确保在每次提示重新生成它之前重新运行它。这可以通过 PROMPT_COMMAND 来完成:

set_prompts() { 
  PS1='\u@\h:\w '                 # <-- Reset PS1 before each run
  message=""
  if [[ $PWD/ == /tmp/* ]]
  then
    message="in /tmp"
  fi
  PS1="\$(echo $message) \$"
}    
PROMPT_COMMAND='set_prompts'      # <-- Run function before every prompt

这按预期工作,并且可以很容易地适应您实际的长代码。

关于git - 在 bash 提示符下为 git status 设置颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24837340/

相关文章:

android - 如何使用命令行生成apk文件?

git - Mathematica 笔记本的版本控制

java - JAVA在命令提示符下构建 war

Gitlab打不开目录

bash - 映射SSL/TLS密码套件及其等效的OpenSSL

bash - 超时执行持续时间而不是命令

windows - 在文件中查找和替换的好工具?

linux - cd 命令 : how to go back an unknown number of levels from current subdirectory to a particular parent directory (unix and dos)

git - 清理 git 历史

git - 如何将 aptana 连接到本地 GIT 存储库