怠惰にgitを使うためのシェル活用術、またはgst一族


[Git Advent Calendar / Jun.](http://qiita.com/advent-calendar/git) 6/12 担当[@T_Hash](https://qiita.com/users/T_Hash)です。

明日も仕事でだるいのですが、怠惰はプログラマの美徳といいます。というわけで僕が日々の仕事で怠惰にgitを使うための設定を共有したいと思います。

## zsh

↓を参考にした設定を.zshrcに記述して、右プロンプトにブランチ名とステータスを表示させています。コマンドを叩かずに状態が見えて非常に便利です。

[git のブランチ名 *と作業状態* を zsh の右プロンプトに表示＋ status に応じて色もつけてみた](http://d.hatena.ne.jp/uasi/20091025/1256458798)

![](https://img.skitch.com/20120612-eychbm7wceue16tripknymfa6k.jpg) ![](https://img.skitch.com/20120612-njse7kamebgxjy5tad2m9c9q4x.jpg)

緑だとクリーンな状態、赤だと未コミットの変更があります。「緑が正常な状態、緑に戻って来たら一段落してコーヒー飲もう」とか考えながら作業をしてます。

あと、zshはgitのコマンドも補完してくれるので地味に重宝します。


## gst: git status

git statusは常に叩くクセを付けた方がいいと思います。オプションは-sと-bがおすすめです。

![](https://img.skitch.com/20120527-rc3958i5n2d5eutbw16wgi29k7.jpg)

![](https://img.skitch.com/20120527-e94ymjxgun9i4fq92cxj7jqcrt.jpg)

で、これにgstというaliasを付けて使っています。

![](https://img.skitch.com/20120612-mj46qbpcpujwe35dy51tmwdw3y.jpg)

僕はもう既にgstが手癖になってて、次の作業を考えながら手が無意識にgst, gst, gst…と叩くようになりました。かの[@sotarok](https://qiita.com/users/sotarok)先生も`gst`を使っているらしいです。やったね。

> @Mekajiki ぼくは gst ですねｗ 考え事してるとだいたい指が gst か ls を打ってます。あとは git branch -a が gb とかですかね。
> Sotaro KARASAWA© (@sotarok) <a href="https://twitter.com/sotarok/status/210388919102095360" data-datetime="2012-06-06T15:13:21+00:00">June 6, 2012</a>


## gst[a/d/v]: status出力のN行目を[add/diff/edit]

今回のメイン（たぶん）。↑のようにgstで表示したファイルに対して「2行目に出てる.vimrcを編集したいな」という時はgstvを使います。

![](https://img.skitch.com/20120612-dbn3fjqgf9717i9qspmaax1xq1.jpg)

これでvimが開き、.vimrcを編集できます。

addしたいときはgsta.

![](https://img.skitch.com/20120612-8ks4e6d5eaqgkg6h43uudsuc92.jpg)

addされてgst結果が変わっていますね。
一方、「gst4行目の.zshrc、何が変更されているか見たい」という時はgstdを使います。

![](https://img.skitch.com/20120612-dyw8rjddqdmwwet5ypedhpb9fb.jpg)

便利ですね。以下、たいしたことやってないですが、コードです。これをPATHに含まれる~/bin/とかに置いてchmod +xで実行権限つけてやれば使えます。

~~~~bash:~/bin/gsta
#!/bin/sh
if [ $# -eq 1 ]; then
    git add `git status -s -b | grep -v "^#" | awk '{print$1="";print}' | grep -v "^$" | awk "NR==$1"`
else
    exit 1
fi
~~~~~

~~~~bash:~/bin/gstd
#!/bin/sh
if [ $# -eq 1 ]; then
    git diff -- `git status -s -b | grep -v "^#" | awk '{print$1="";print}' | grep -v "^$" | awk "NR==$1"`
else
    exit 1
fi
~~~~~

~~~~bash:~/bin/gstv
#!/bin/sh
if [ $# -eq 1 ]; then
    vim `git status -s -b | grep -v "^#" | awk '{print$1="";print}' | grep -v "^$" | awk "NR==$1"`
else
    exit 1
fi

~~~~~



## statusついでにstash listも表示する

作業中に急に対応する必要のあるバグが出てきたときなど、stash saveでいったん作業を退避させてからバグ対応、stash popで元に戻すということをやります。

たまにstashしていたことをど忘れすることがあるので、先ほどのgstでstatusを見るとき、ついでにstash中の変更を表示させるようにしてみたところ、とても安心感あって良い感じなのでオススメです。

~~~~~~~zsh
% which gst
gst: aliased to git st && g stash list
~~~~~~~~

~~~~~~~.zshrc
alias gst='git st && g stash list'
~~~~~~~~

![](https://img.skitch.com/20120612-bpa49wnupjka6kdx1yqa17e4jk.jpg)

* 余談
  * 確かどこかでgitメンテナの方が、stashはsave -> popで戻すのではなく、save -> apply -> (確認) -> dropというお行儀がよいフローを推奨していた記憶があります。


## gcm: git commit

~~~~~~bash:~/bin/gcm
#!/bin/sh
git commit -m "$*"
~~~~~~

そのまんまで、stageしたものをcommitするaliasです。

![gcm](https://img.skitch.com/20120527-1mc8724che171in7mnhbpcga4c.jpg)


## gch: git cherry -v

cherry-pickはよく使われているのですが、cherryも結構便利です。
git cherryは、かつて分岐したブランチ間の差分commit一覧を表示します。

例として、`ng_solr`ブランチに含まれているcommitと`ok_solr`ブランチに含まれているcommitの差分を出力してみます。`-v`オプション付きがおすすめです。

~~~~~~~~~diff:cherry
% git checkout ng_solr
% git cherry -v ok_solr
+ 608e08404aa15c7cf1cc3bad4311f4a9edd9e78d install Sunspot (Solr on Rails)
+ a5d09e3ee1c1daf40a29b0f5a6cc94e4a2ff16d8 Mongoid用Sunspotカスタマイズ
+ a7c11ee46578d78650512c06446e31722f0568b5 seachable定義を追加
- c13b510b8e1ac02350058ca50c77a8f72ba3cf80 index再生成用rakeタスクの作成
- 5009ffcb5b16cc77ceff2117c2a435017db96247 ArticleControllerのリファクタリング
+ 67294858d72d4fb8d6ae44e43485e08744bd67de なんかいろいろほげほげ
~~~~~~~~~

~~~~~.zshrc
alias gch='git cherry -v'
~~~~~

これをcutとかawkでいじってgit showに渡してやれば、該当コミットの中身が確認できる。

~~~~~bash:~/bin/gchs
#!/bin/sh

if [ $# -eq 2 ]; then
    git show `git cherry -v $1 | awk '{print $2}' | awk "NR==$2"`
else
    exit 1
fi
~~~~~~~

名前はgit cherry+showでgchs. 使い方は

~~~~~
$ gchs ok_solr 2
~~~~~

とやれば2個目のcommit内容が表示される。

masterから作業ブランチの差分を順々に表示していくと、コードレビューなんかに便利かなと。


## git log 

log系はいろいろ工夫のしどころがある。一部、最近はTigでよくねと思ってる機能もあるけど一応。

### glgg

脳内ではゲルググと呼んでる。

~~~~~.zshrc
alias glgg='git logg'
~~~~~

~~~~~.gitconfig
[alias]
    logg = log --stat --pretty=format:'%Cblue%h %Cgreen%ar %Cred%an %Creset%s %Cred%d'
~~~~~~

### glg

~~~~~.zshrc
alias glg='git logg | head'
~~~~~

単なるゲルググのheadだが、ゲルググより利用頻度高。直近commitの内容をさっくり確認。

![](https://img.skitch.com/20120527-8pkqir1hds8fyatmc477ibdn62.jpg)

白で表示されて欲しい文字が赤色で出るのが目下の悩み


### その他ログ系tips

* loggr

~~~~~~.gitconfig
[alias]
    loggr = log --graph --date-order --pretty=format:'%Cblue%h %Cgreen%ci %Cred%an %Cblue%m %Creset%s %Cred%d'
~~~~~~

命名: logg + graph。キャプチャは取れないが多人数開発（つまり仕事）でマージ関係を把握する時便利

![](https://img.skitch.com/20120527-m7t7kmc8haq58rrmgrdpff6r5j.jpg)


* tig

しっかり見るときはtigオススメ

~~~~
% brew install tig
~~~~

![](https://img.skitch.com/20120527-kti8mfbbxjuify7p8r3c4d51nj.jpg)


## いじょ

俺の方がもっと怠惰にgitを使ってる！という人は是非教えて下さい。もっとラクしたいです。