Cygwin のプロンプトに Git のブランチを表示する(シンタックスエラーが発生した場合の対策あり)

  • 6
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

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 を編集する

.bashrcgit-prompt.sh を読み込む処理を追加します。/etc/profile.d/ に配置したのでログイン時には自動的に読み込まれているのですが,非ログインシェルとして起動した場合にも読み込まれるように書いておきます。

.bashrc
source /etc/profile.d/git-prompt.sh

環境変数 $PS1$(__git_ps1) を埋め込みます。__git_ps1 というのは git-prompt.sh で定義されている関数です。以下の例では見づらくなるため省略していますが,エスケープシーケンスを使って色をつけることもできます。

.bashrc
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 以外は任意の値をセットすればオプションが有効になります。

.bashrc
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 のセクションをご覧ください。

.bashrc
export PS1='\u@\h \w$(__git_ps1)'$'\n$ '

なお,Git for Windows でも igncr が有効になっているようですが,ブランチの表示にはバッククォート形式のコマンド置換を使っているので(自分で環境変数を上書きしない限りは)問題ありません。

参考資料