インデントコミットで真犯人がわからなくなった場合の git blame

例えば [fluentd](https://github.com/fluent/fluentd) の [lib/fluent/output.rb](https://github.com/fluent/fluentd/blob/43c4844d6cb06644407e772ce080c05d16f43641/lib/fluent/output.rb#L181) ファイルに

```rb
config_param :queued_chunk_flush_interval, :time, :default => 1
```

を追加したコミットがどれかを探したいとします。

しかし、git blame を見ると[こんなかんじ](https://github.com/fluent/fluentd/blame/master/lib/fluent/output.rb#)に、インデントコミットによってほぼ全ての履歴が上塗りされていてどれだかわからない、みたいな状況にどうやって真犯人を探そうかという話です。

![901fb2ac4a7f791b5d2ad8660fdd5545.png](https://qiita-image-store.s3.amazonaws.com/0/9641/50b72369-ad35-c48e-5d0f-2f9d0800b0bb.png)

# 1. git blame -w を使う

インデントコミットを無視したいだけであれば git blame の `-w` オプションが使える。-w は比較の際に whitespace を無視してくれるオプション。git diff にもあるよね。

```bash
$ git blame -w lib/fluent/output.rb
... (省略)
14d01c71 (Masahiro Nakagawa  2013-03-27 03:56:51 +0900 181)     config_param :queued_chunk_flush_interval, :time, :default => 1
... (省略)
```

おぉ、見つかった。14d01c71 か => https://github.com/fluent/fluentd/commit/14d01c71eb7b0d788184cdd0af6085cdceefa1b8

# 2. git log -S を使う

git log の -S オプションを使う。-S は指定した文字列にマッチする + diff のある commit log のみ出してくれるオプション。-G で正規表現指定もできる。

```bash
$ git log -S 'config_param :queued_chunk_flush_interval, :time, :default => 1' lib/fluent/output.rb

commit 14d01c71eb7b0d788184cdd0af6085cdceefa1b8
Author: Masahiro Nakagawa <repeatedly@gmail.com>
Date:   Wed Mar 27 03:56:51 2013 +0900

    Add queued_chunk_flush_interval to BufferedOutput
```

おぉ、見つかった。14d01c71 か => https://github.com/fluent/fluentd/commit/14d01c71eb7b0d788184cdd0af6085cdceefa1b8

# 3. [git-strata](http://shyouhei.tumblr.com/post/67314913322/git) を使う

-w オプション実装してくれるっぽいのでちょっと待ってね。

# 4. [vcs-ann](https://github.com/akr/vcs-ann) を使う

[@tanaka_akr](https://twitter.com/tanaka_akr) さんが [vcs-ann](https://github.com/akr/vcs-ann) というものを作ったと[教えてくれた](https://twitter.com/tanaka_akr/status/450896195628437504)ので、試してみた。

w3m で開いて青文字部分のリンクをクリックして、対話的に履歴を追いかけていくことができる！

```bash
$ gem install vcs-ann
$ vcs-ann lib/fluent/output.rb
```

まずは日付をクリック

![520935f87f67180dd9e3da4ebcfa3478.png](https://qiita-image-store.s3.amazonaws.com/0/9641/74a47f7b-e6cf-b462-7a92-ce1549057a5f.png)

インデントコミットの差分が出た。今回はインデント前の所を追いたいので - のリンクをクリック

![スクリーンショット 2014-04-01 17.09.58.png](https://qiita-image-store.s3.amazonaws.com/0/9641/3c179b4b-24af-2134-2e64-9ab63475129e.png)


次のコミットが出て来たのでまた日付をクリック

![64aa5e5dad1a470a2c52eb7cc3ed39b7.png](https://qiita-image-store.s3.amazonaws.com/0/9641/6ea53e1d-6a43-9a1e-009c-1321547e58ab.png)

出て来た！

![9b208939c36270ab5fa336d1db844457.png](https://qiita-image-store.s3.amazonaws.com/0/9641/264dce45-65b5-110a-cffe-364d53990d95.png)

これは便利なんじゃないですかね？

# 5. tig blame を使う

[@a_matsuda](https://twitter.com/a_matsuda) さんに教えてもらいました。[tig](https://github.com/jonas/tig) blame を使えば , で辿れるとのこと。

```bash
$ tig blame lib/fluent/output.rb
```

![640391058803a20000762e78fdb12f08.png](https://qiita-image-store.s3.amazonaws.com/0/9641/97af0759-4b49-d3d1-7b30-146db87b27db.png)

最初はインデントコミットのハッシュが出て来たので、カーソル行に対するその前のコミットを
, で辿る。次の blame が出て来た。

![c0582d883ad70d5aa82f2000cff6dd91.png](https://qiita-image-store.s3.amazonaws.com/0/9641/ad2fc5dc-1937-f191-23b6-95289e7779ad.png)

14d01c71 ... コレかな？ Enter を押すと diff が見れるので確認。

![74b10a9334b8a11a5243b3addc8427de.png](https://qiita-image-store.s3.amazonaws.com/0/9641/ad74ff3f-5ef9-1714-bf52-09c0c8cc6104.png)

これだ！見つかった！


# 最後に

もっとありそうな気がするのでコメントウェルカム！