シェルに zsh を、バージョン管理に git を使う場合、zsh の vcs_info 機能が便利です。これは、バージョン管理システムの情報をコマンドプロンプトに表示できる機能です。
- 動機(1):gitを使うワークフローでは、頻繁にブランチを作って切り替えるのが普通です。これは優れたワークフローですが、時として現在のブランチが何だったか見失う場合があります。このため、自分が現在どのブランチにいるかを常に把握しておきたいです。
- 解決(1):現在のブランチをコマンドプロンプトに表示します。
- 動機(2):gitでは変更をリポジトリに反映する際に、ワーキングコピーからステージングエリアへの反映(git add)、ステージングエリアからローカルリポジトリへの反映(git commit)、ローカルリポジトリからリモートリポジトリへの反映(git push)、と段階があります。これはgitの長所ですが、時としてどれかの処理を忘れるミスが発生してしまいます。このため、現在なんの処理が残っているのかを常に把握しておきたいです。
- 解決(2):現在の変更の状態(未addがあるか、未commitがあるか、未pushがあるか)をコマンドプロンプトに表示します。
- 動機(3):gitには変更を一時的に格納しておくstash機能があります。これは便利ですが、時としてstashに入れたまま取り出すのを忘れてしまうミスが発生してしまいます。このため、stashの有無を常に把握しておきたいです。
- 解決(3):stashの状態をコマンドプロンプトに表示します。
そんなわけで、僕の .zshrc から vcs_info の設定を抜き出して公開してみます。
# vcs_info
autoload vcs_info
# gitのみ有効にする
zstyle ":vcs_info:*" enable git
# commitしていない変更をチェックする
zstyle ":vcs_info:git:*" check-for-changes true
# gitリポジトリに対して、変更情報とリポジトリ情報を表示する
zstyle ":vcs_info:git:*" formats "%c%u[%b:%r]"
# gitリポジトリに対して、コンフリクトなどの情報を表示する
zstyle ":vcs_info:git:*" actionformats "%c%u<%a>[%b:%r]"
# addしていない変更があることを示す文字列
zstyle ":vcs_info:git:*" unstagedstr "<U>"
# commitしていないstageがあることを示す文字列
zstyle ":vcs_info:git:*" stagedstr "<S>"
# git:まだpushしていないcommitあるかチェックする
my_git_info_push () {
if [ "$(git remote 2>/dev/null)" != "" ]; then
local head="$(git rev-parse HEAD)"
local remote
for remote in $(git rev-parse --remotes) ; do
if [ "$head" = "$remote" ]; then return 0 ; fi
done
# pushしていないcommitがあることを示す文字列
echo "<P>"
fi
}
# git:stashに退避したものがあるかチェックする
my_git_info_stash () {
if [ "$(git stash list 2>/dev/null)" != "" ]; then
# stashがあることを示す文字列
echo "{s}"
fi
}
# vcs_infoの出力に独自の出力を付加する
my_vcs_info () {
vcs_info
echo $(my_git_info_stash)$(my_git_info_push)$vcs_info_msg_0_
}
プロンプトは例えば次のように設定します。
# プロンプト定義の中で置換を使用する
setopt prompt_subst
# プロンプト定義
RPROMPT=$'$(my_vcs_info)'
これにより、次のような表示になります。ブランチ名とリポジトリ名が常に表示されます。
% [branch:repository]
また、stashがある、未pushがある、未commitがある、未addがある、という状態では次のような表示になります。
% {s}<P><S><U>[branch:repository]
このおかげで、git が快適に使えています。ありがとう zsh。
補足:
- 僕は実際にはPROMPTに含めて表示していますが、ここでは簡単に試しやすいRPROMPTを使ってみました。
- vcs_info機能は様々なバージョン管理システムをサポートしますが、僕はgitのみで使うよう設定しています。
なお、vcs_info の詳細は man zshcontrib に記載があります。最新の zsh だと vcs_info に hook function が追加されているので、my_vcs_info なんて作らずにもう少し美しく書けそうです。