その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

git stashで作業内容をスタックに積んでる時に、それをコンソールに表示しておく方法

git stash便利ですよね!
「ちょっと別のブランチをcheck out したいな」みたいな時に大変重宝しています。
ただ、いろいろ便利なgit stash ですが、git stash pop をし忘れると色々と悲劇が起こります。
例えば……

・「あれ、前にここの部分は修正したはずなのに、なんで元に戻ってるんだろう」
疑問に思いながらもソースコードを修正してcommit → 残念! git stash pop のし忘れでした!
作業していたこの1時間は徒労!! イエーイ!!!

・「数件前のcommit で修正したってコミットログに書いてるけど、修正されてないよ」
残念! git stash pop をし忘れた為にそのコミットには反映されてませんでした!
で、git stash pop してみる → おや! 直前にcommit した内容と衝突してconflict してるぞ!! 面倒くせえ!

・「スタックに作業内容がたくさん積まれてるなぁ……どれだったっけ。まあいいや。とりあえずgit stash pop、っと」
残念! そのpop した作業内容は現在行なっている作業とは異なる内容でした!
謎のマージがガンガン行われているぞ!!

などなど……

「stash した内容は、その用事が終わったらすぐにpop しないと駄目だよ! 忘れずpop しようね!」

というルールを守れるのが一番好ましい訳ですが、stash した事自体忘れてしまう事が多々あります。にんげんだもの。*1
なので、stash した事を忘れない為にも、コンソール画面に「スタックに作業内容が積まれてるぞ! 早くpop しろ!」
警告を出して、悲劇を未然に防ぐ方法を以下に記したいと思います。


よういするもの

  • git-completion


てじゅん

  1. git-completion をインストールする(もう既に入ってる人は省略)
  2. .bashrc を書き換える
  3. /etc/bash_completion.d/git を書き換える


やりかた

1. git-completion をインストールする
Linux の場合はapt-get なりyum なりでインストールしましょう

例)
$ sudo apt-get install git-completion

Cygwin の場合はsetup.exe を使うか、apt-cyg(cyg-apt) を使ってインストールしましょう
[setup.exe を使う場合]

パッケージを選択する画面で、こんな感じでInstall するように指示すればオッケーです。

[apt-cyg(cyg-apt) を使う場合]
apt-cyg かcyg-apt が入っている前提で。以下のようにコマンドを打てばインストールされると思います。

例)
$ apt-cyg install git-completion

2. .bashrc を書き換える
環境変数PS1 に"\$(__git_ps1)"という文字列を組み込むと、
git のワークツリーがあるディレクトリに移動した時、ブランチ名がコンソールに表示されるようになります。
更にオプションを指定してあげると、様々な情報を提供してくれるようになります。*2

今回はstash に何かが入っている時に知らせてくれるようにしたいので、
"GIT_PS1_SHOWSTASHSTATE" という変数を有効にしてあげます。
なので、以下の様に.bashrc を書き換えます。

例)
export GIT_PS1_SHOWSTASHSTATE=1
export PS1="$PS1\$(__git_ps1)"
すると、stash されてスタックに何かが積まれている時にはブランチ名の後に'$'が付加されて教えてくれるようになります。

3. /etc/bash_completion.d/git を書き換える
これまでの手順で、stash されている事を教えてくれるようにはなりましたが、'$'マークだけだと味気ないというか、
最悪の場合、見落とす可能性があるので、表示する文字列を変えます。
(念のため、/etc/bash_completion.d/git のバックアップを取っておいたほうが良いかもしれません)

/etc/bash_completion.d/git に
if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
    git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$"
という部分があるので、この末尾部分(s="$")を書き換えます。

例)
if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then
    git rev-parse --verify refs/stash >/dev/null 2>&1 && s=":POPしろ"
こう書き換えると、スタックに積まれている時にはブランチ名の横に":POPしろ"と表示されるようになります。
これなら見落とす心配も少なくなりますね。

以上で作業は終了です。


本当はこうしたかった

":POPしろ"を赤い文字で表示して、警告感を煽ろうと試みたんですが、
s="\[\e[1;31m\]:POPしろ\[\e[00m\]"
と書いてやっても色が変わらず、エスケープシーケンスが文字列のまま表示されちゃうんですよね。
まあ、エスケープシーケンスがそのまま表示されれば、
それはそれで目を引くので警告としての役割はバッチリ果たしますがw

「こうすりゃできるよー」と教えてくれる方、歓迎です。

*1:「忘れてしまうから、stash した後はトイレに立たないこと」という自分ルールが出来るまでに至りました

*2:詳しくは→[http://d.hatena.ne.jp/gnarl/20110901/1314846241]