zshのvcs_infoの挙動のお話
vcs_infoというのはzshのプロンプトに今いるリポジトリの情報を表示してくれるものです。
zsh で Git の作業コピーに変更があるかどうかをプロンプトに表示する方法
これすごく便利なんですが、異なるVCSのリポジトリがネストした状況下で想定した動作をしません。
例えば $HOME (~/) 以下をバージョン管理している状況でその下に個別のバージョン管理しているプロジェクトを置いている場合などです。
vcs_infoの設定を以下のようにしている場合
zstyle ':vcs_info:*' enable git hg zstyle ':vcs_info:*' formats '(%s:%b)' PROMPT="%1v%# "
gitリポジトリ以下にmercurialのリポジトリを作成してcdした場合にプロンプトの表示がgitのままになります。
% git init top-repo && cd top-repo (git:master)% hg init nested-repo && cd nested-repo (git:master)%
これはvcs_infoが zstyle ':vcs_info:*' enable git hg の先頭から順に調べて行って、そのVCSのリポジトリが見つかった時点で確定するためです。
gitやmercurialなどはカレントディレクトリにリポジトリが見つからない場合、上の階層に向かって再帰的に探すようになっています。そのため、前述のような動作になるわけです。
実際のコードは /usr/share/zsh/functions/VCS_Info/vcs_info の138行目辺りにある以下のコードです。 *1
... for vcs in ${enabled} ; do [[ -n ${(M)disabled:#${vcs}} ]] && continue if (( ${+functions[VCS_INFO_detect_${vcs}]} == 0 )) ; then printf 'vcs_info: configured unknown backend: '\''%s'\''\n' ${vcs} printf 'vcs_info: use '\''vcs_info_printsys'\'' to find supported systems.\n' continue fi vcs_comm=() VCS_INFO_get_cmd VCS_INFO_detect_${vcs} && (( found = 1 )) && break done ...
これの解決策としては、ネストしてるリポジトリの一番上のVCSをvcs_infoのenableの一番後にもってくれば大丈夫です。
本家ML(http://www.zsh.org/mla/users/2011/msg00676.html)にもありますね。