Cygwin の Bash プロンプトに Git のブランチの情報を表示させる方法です。手順自体は多くの方が公開してくださっているものと同じなのですが,改行コードにまつわる Cygwin 環境ならでは(?)の問題に遭遇したので,その対策もあわせてメモとして残しておきたいと思います。
ブランチ名を表示する
git-prompt.sh を入手する
git の GitHub リポジトリから git-prompt.sh
を入手し,適当な場所に配置します。わたしは Git for Windows(msysGit)にあわせて /etc/profile.d/
に置きました。git-prompt.sh
の冒頭に書いてある説明では ~/.git-prompt.sh
に置くことを想定しているようです。
$ wget https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh
$ mv git-prompt.sh /etc/profile.d/
.bashrc を編集する
.bashrc
に git-prompt.sh
を読み込む処理を追加します。/etc/profile.d/
に配置したのでログイン時には自動的に読み込まれているのですが,非ログインシェルとして起動した場合にも読み込まれるように書いておきます。
source /etc/profile.d/git-prompt.sh
環境変数 $PS1
に $(__git_ps1)
を埋め込みます。__git_ps1
というのは git-prompt.sh
で定義されている関数です。以下の例では見づらくなるため省略していますが,エスケープシーケンスを使って色をつけることもできます。
export PS1='\u@\h \w$(__git_ps1)\n\$ '
これで Git 管理下のディレクトリに入るとブランチ名が表示されるようになります。
ブランチの状態を表示する
環境変数を設定するとブランチのさまざまな状態を表示することができます。たとえば以下のような環境変数が利用できるようです。
環境変数 | 表示される内容 |
---|---|
GIT_PS1_SHOWDIRTYSTATE | ステージされていない変更がある場合(unstaged)に "* " を表示し,ステージ済みだがコミットされていない変更がある場合(staged)に "+ " を表示する。 |
GIT_PS1_SHOWUNTRACKEDFILES | 追跡されていないファイルがある場合(untracked)に "% " を表示する。 |
GIT_PS1_SHOWSTASHSTATE |
git stash で退避した作業がある場合(stashed)に "$ " を表示する。 |
GIT_PS1_SHOWUPSTREAM | ブランチと Upstream の差を表示する。ブランチが遅れている場合(behind)に "< " を,先行している場合(ahead)に "> " を,ブランチと Upstream にそれぞれ独自の更新がある場合(diverged)に "<> " を,最新の場合(up-to-date)に "= " を表示する。 |
GIT_PS1_SHOWUPSTREAM
以外は任意の値をセットすればオプションが有効になります。
export GIT_PS1_SHOWDIRTYSTATE=1
export GIT_PS1_SHOWSTASHSTATE=1
export GIT_PS1_SHOWUNTRACKEDFILES=1
export GIT_PS1_SHOWUPSTREAM="auto"
オプションの詳しい使い方は git-prompt.sh
の最初の方に書いてありますので,興味のある方はご確認ください。
シンタックスエラーが発生した場合
構文解析でエラー
Cygwin 環境では $PS1
のコマンド置換でシンタックスエラーが出ることがあります。
-bash: command substitution: line 1: syntax error near unexpected token `)'
-bash: command substitution: line 1: `__git_ps1)'
これは改行コード CR
を無視する Cygwin 独自のシェルオプション igncr
による影響のようです。igncr
が設定されている場合,$PS1
内で $( )
形式のコマンド置換の後に \n
が続くと構文解析に失敗してしまいます。バッククォートによる旧式のコマンド置換ではこの現象は発生しません。
エラーへの対処法
この問題への対策としては以下のようなものが考えられます。
-
igncr
を off にする - バッククォート形式のコマンド置換を使う
-
$''
でエスケープシーケンスを評価する
ここでは 3 つ目の方法を紹介します。
文字列のクォートに $''
を使うと,エスケープシーケンスをデコードして置き換えることができます。この場合,$PS1
には '\n'
ではなくて「改行文字」がそのまま含まれることになります。詳しくは man bash
の QUOTING のセクションをご覧ください。
export PS1='\u@\h \w$(__git_ps1)'$'\n$ '
なお,Git for Windows でも igncr
が有効になっているようですが,ブランチの表示にはバッククォート形式のコマンド置換を使っているので(自分で環境変数を上書きしない限りは)問題ありません。