zshのプロンプトにgitの状態表示 - 未add/未commit/未push/untracked(未追跡)に対応
zshのプロンプトにgitの状態(add/commit/push)を表示する方法に関しては、こことここを参考にしています。
今回はそこにプラスしてUntracked(未追跡)なファイルが存在しているかどうかも分かるようにzshのプロンプトに表示させます。
さらに状態を表す記号は全てブランチ名の”前”に付けるようにしました。
その他、git init直後などでHEADがまだ存在しない場合にも正常に表示されるようにするための対応、リモートリポジトリが存在しない場合に未pushと認識しないように対応したました。
っでこんな感じになりました。
.zshrcに設定する内容はこんな感じ
### zshプロンプト設定 # カラーの設定を$fg[red]のように人がわかるような書き方ができる autoload -Uz colors colors # # Color定義(あとで変更しやすいように) # DEFAULT=$'%{\e[0;0m%}' RESET="%{${reset_color}%}" GREEN="%{${fg[green]}%}" BOLD_GREEN="%{${fg_bold[green]}%}" BLUE="%{${fg[blue]}%}" BOLD_BLUE="%{${fg_bold[blue]}%}" RED="%{${fg[red]}%}" BOLD_RED="%{${fg_bold[red]}%}" CYAN="%{${fg[cyan]}%}" BOLD_CYAN="%{${fg_bold[cyan]}%}" YELLOW="%{${fg[yellow]}%}" BOLD_YELLOW="%{${fg_bold[yellow]}%}" MAGENTA="%{${fg[magenta]}%}" BOLD_MAGENTA="%{${fg_bold[magenta]}%}" WHITE="%{${fg[white]}%}" setopt prompt_subst autoload -Uz add-zsh-hook # # Gitの状態表示 # # 記号について # - : WorkingTreeに変更がある場合(Indexにaddしていない変更がある場合) # + : Indexに変更がある場合(commitしていない変更がIndexにある場合) # ? : Untrackedなファイルがある場合 # * : remoteにpushしていない場合 # autoload -Uz vcs_info zstyle ':vcs_info:*' enable git svn hg bzr zstyle ':vcs_info:*' formats '(%s)-[%b]' zstyle ':vcs_info:*' actionformats '(%s)-[%b|%a]' zstyle ':vcs_info:(svn|bzr):*' branchformat '%b:r%r' zstyle ':vcs_info:bzr:*' use-simple true autoload -Uz is-at-least if is-at-least 4.3.10; then # zshが4.3.10以上の場合 zstyle ':vcs_info:git:*' check-for-changes true zstyle ':vcs_info:git:*' stagedstr "+" zstyle ':vcs_info:git:*' unstagedstr "-" zstyle ':vcs_info:git:*' formats '%s,%u%c,%b' zstyle ':vcs_info:git:*' actionformats '%s,%u%c,%b|%a' fi function _update_vcs_info_msg() { psvar=() LANG=en_US.UTF-8 vcs_info local _vcs_name _status _branch_action if [ -n "$vcs_info_msg_0_" ]; then _vcs_name=$(echo "$vcs_info_msg_0_" | cut -d , -f 1) _status=$(_git_untracked_or_not_pushed $(echo "$vcs_info_msg_0_" | cut -d , -f 2)) _branch_action=$(echo "$vcs_info_msg_0_" | cut -d , -f 3) psvar[1]="(${_vcs_name})-[${_status}${_branch_action}]" fi # 右側プロンプト RPROMPT="${RESET}%1(v|${RED}%1v|)${RESET}${BOLD_YELLOW}${VIRTUAL_ENV:+($(basename "$VIRTUAL_ENV"))}${RESET}[${MAGENTA}%D{%Y/%m/%d %H:%M:%S}${RESET}]${RESET}" } add-zsh-hook precmd _update_vcs_info_msg # # Untrackedなファイルが存在するか未PUSHなら記号を出力 # Untracked: ? # 未PUSH: * # function _git_untracked_or_not_pushed() { local git_status head remotes stagedstr local staged_unstaged=$1 not_pushed="*" untracked="?" # カレントがgitレポジトリ下かどうか判定 if [ "$(git rev-parse --is-inside-work-tree 2> /dev/null)" = "true" ]; then # statusをシンプル表示で取得 git_status=$(git status -s 2> /dev/null) # git status -s の先頭が??で始まる行がない場合、Untrackedなファイルは存在しない if ! echo "$git_status" | grep "^??" > /dev/null 2>&1; then untracked="" fi # stagedstrを取得 zstyle -s ":vcs_info:git:*" stagedstr stagedstr # git status -s の先頭がAで始まる行があればstagedと判断 if [ -n "$stagedstr" ] && ! printf "$staged_unstaged" | grep "$stagedstr" > /dev/null 2>&1 \ && echo "$git_status" | grep "^A" > /dev/null 2>&1; then staged_unstaged=${staged_unstaged}${stagedstr} fi # HEADのハッシュ値を取得 # --verify 有効なオブジェクト名として使用できるかを検証 # --quiet --verifyと共に使用し、無効なオブジェクトが指定された場合でもエラーメッセージを出さない # そのかわり終了ステータスを0以外にする head=$(git rev-parse --verify -q HEAD 2> /dev/null) if [ $? -eq 0 ]; then # HEADのハッシュ値取得に成功 # リモートのハッシュ値を配列で取得 remotes=($(git rev-parse --remotes 2> /dev/null)) if [ "$remotes[*]" ]; then # リモートのハッシュ値取得に成功(リモートが存在する) for x in ${remotes[@]}; do # リモートとHEADのハッシュ値が一致するか判定 if [ "$head" = "$x" ]; then # 一致した場合はPUSH済み not_pushed="" break fi done else # リモートが存在しない場合 not_pushed="" fi else # HEADが存在しない場合(init直後など) not_pushed="" fi # Untrackedなファイルが存在するか未PUSHなら記号を出力 if [ -n "$staged_unstaged" -o -n "$untracked" -o -n "$not_pushed" ]; then printf "${staged_unstaged}${untracked}${not_pushed}" fi fi return 0 }
状態を表す記号は以下のようになっています。
- : WorkingTree変更がある場合(Indexにaddしていない変更がある場合) + : Indexに変更がある場合(commitしていない変更がIndexにある場合) ? : Untrackedなファイルがある場合 * : remoteにpushしていない場合(リモートが設定されている場合のみ)
記号を変更したい方は
zstyle ':vcs_info:git:*' stagedstr "+" zstyle ':vcs_info:git:*' unstagedstr "-" local staged_unstaged=$1 not_pushed="*" untracked="?"
の行の記号を変更して下さい。
記号の出力位置とかが気に食わないよって方は
psvar[1]="(${_vcs_name})-[${_status}${_branch_action}]"
の部分を修正して下さい。
上記の設定は私のgithub(yonchu/dotfiles)にて公開しています。
良かったら見てみたください。