git bisect good/badを間違えた時、やり直す方法

[参考: Undoing a git bisect mistake](http://stackoverflow.com/questions/8594758/undoing-a-git-bisect-mistake)

めったに必要になる機会がないので、やり直しができるということだけ覚えておけば良いと思う。
[git bisect replay] , [Undo git bisect]などのキーワードを覚えておけば良い。

```rb
$ git bisect log > bisect.log

$ vi bisect.log
# 最後の方の間違えた行を消す

$ git bisect replay bisect.log
```

---

### git bisectの全体の流れ

```rb
$ git lol
* 03cbace (HEAD, master) ERROR3
* 94b4932 ERROR2
* acab3aa BUG
* 3f0a1dc OK5
* c2f783b OK4
* 9642184 OK3
* 208588d OK2
* 94617c5 Initial commit

# git bisect start <bad-commit> <good-commit>
$ git bisect start 03cbace 9642184
Bisecting: 2 revisions left to test after this (roughly 1 step)
[3f0a1dc1ebad46d2af99b588f93d02572c230697] OK5

# BUGがあるかどうか確認
$ grep BUG sample.txt

$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[94b49321e7b9453d5c9d9b82f19596c5fb98e66f] ERROR2

$ grep BUG sample.txt
BUG

$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[acab3aac0dbed38eaed3ac339acc7fb70f9e73ad] BUG

$ grep BUG sample.txt
BUG

# 間違えてgoodにしてしまう
$ git bisect good
94b49321e7b9453d5c9d9b82f19596c5fb98e66f is the first bad commit
Date:   Wed Feb 11 21:33:25 2015 +0900

    ERROR2

:100644 100644 07ffce001eeafae0fa0d8342879f3cd11f91b506 f95c068d1da16c5bd8bffe7ea0eb3446ed193ae1 M  sample.txt

# やり直す
$ git bisect log > bisect.log

$ cat bisect.log
# bad: [03cbaceb177d3ffda82627f70f8254ae4a483aeb] ERROR3
# good: [9642184e7c3704aee3a4f7fb4e89f473e0d14b90] OK3
git bisect start '03cbace' '9642184'
# good: [3f0a1dc1ebad46d2af99b588f93d02572c230697] OK5
git bisect good 3f0a1dc1ebad46d2af99b588f93d02572c230697
# bad: [94b49321e7b9453d5c9d9b82f19596c5fb98e66f] ERROR2
git bisect bad 94b49321e7b9453d5c9d9b82f19596c5fb98e66f
# good: [acab3aac0dbed38eaed3ac339acc7fb70f9e73ad] BUG
git bisect good acab3aac0dbed38eaed3ac339acc7fb70f9e73ad
# first bad commit: [94b49321e7b9453d5c9d9b82f19596c5fb98e66f] ERROR2

# ファイルの最後の方の間違えてgoodした部分を消す
$ vi bisect.log

$ cat bisect.log
# bad: [03cbaceb177d3ffda82627f70f8254ae4a483aeb] ERROR3
# good: [9642184e7c3704aee3a4f7fb4e89f473e0d14b90] OK3
git bisect start '03cbace' '9642184'
# good: [3f0a1dc1ebad46d2af99b588f93d02572c230697] OK5
git bisect good 3f0a1dc1ebad46d2af99b588f93d02572c230697
# bad: [94b49321e7b9453d5c9d9b82f19596c5fb98e66f] ERROR2
git bisect bad 94b49321e7b9453d5c9d9b82f19596c5fb98e66f

$ git bisect replay bisect.log
Previous HEAD position was acab3aa... BUG
Switched to branch 'master'
Bisecting: 2 revisions left to test after this (roughly 1 step)
[3f0a1dc1ebad46d2af99b588f93d02572c230697] OK5
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[acab3aac0dbed38eaed3ac339acc7fb70f9e73ad] BUG

$ grep BUG sample.txt
BUG

$ git bisect bad
acab3aac0dbed38eaed3ac339acc7fb70f9e73ad is the first bad commit
Date:   Wed Feb 11 21:33:06 2015 +0900

    BUG

:100644 100644 4bccd10bb429d2db9af75fdcde84a1055085cfbb 07ffce001eeafae0fa0d8342879f3cd11f91b506 M  sample.txt

$ git lol
* acab3aa (HEAD, refs/bisect/bad) BUG
* 3f0a1dc (refs/bisect/good-3f0a1dc1ebad46d2af99b588f93d02572c230697) OK5
* c2f783b OK4
* 9642184 (refs/bisect/good-9642184e7c3704aee3a4f7fb4e89f473e0d14b90) OK3
* 208588d OK2
* 94617c5 Initial commit

$ git bisect reset
Previous HEAD position was acab3aa... BUG
Switched to branch 'master'
```

---

### おまけ (git bisect run)

ついでなので、前から気になっていた、自動で一気にgit bisectできる`git bisect run`を少し検証

コマンドラインレベルでできる内容であれば、問題なく動くことが分かった。
Rubyならダメな時に`exit(1)`, 良い時に`exit(0)`を返す。
シェルスクリプトやRubyスクリプトで簡単にかける検証であれば使える。

RSpecでひとつのテストだけを走らせるパターンでもできた。

```rb
git bisect run rspec spec/feature/some_spec.rb:123
```

実際には、Webアプリであることが多いので、`rails s`、ブラウザで確認、停止(Ctrl+C)のことが多いから、これらをスクリプトで表現できないかとか考える。

今回のgit bisectのテキストファイルの内容での検証

```rb
$ git bisect run ruby -e 'File.read("sample.txt").include?("BUG") ? exit(1) : exit(0)'
running ruby -e File.read("sample.txt").include?("BUG") ? exit(1) : exit(0)
Bisecting: 0 revisions left to test after this (roughly 1 step)
[94b49321e7b9453d5c9d9b82f19596c5fb98e66f] ERROR2
running ruby -e File.read("sample.txt").include?("BUG") ? exit(1) : exit(0)
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[acab3aac0dbed38eaed3ac339acc7fb70f9e73ad] BUG
running ruby -e File.read("sample.txt").include?("BUG") ? exit(1) : exit(0)
acab3aac0dbed38eaed3ac339acc7fb70f9e73ad is the first bad commit
commit acab3aac0dbed38eaed3ac339acc7fb70f9e73ad

    BUG

:100644 100644 4bccd10bb429d2db9af75fdcde84a1055085cfbb 07ffce001eeafae0fa0d8342879f3cd11f91b506 M	sample.txt
bisect run success
```