Railsのissueに書いてある再現コードを使ってgit bisectする方法

備忘録。

具体的な例

先日に登録されたissueを例にしてみる。

github.com

再現コードを少し書き換える

v5.2.3と6.0.0.rc2でsqlite3の依存周りでエラーが出たので、Gemfileのあたりを少しだけ弄った。

# frozen_string_literal: true

require "bundler/inline"

gemfile = File.read(File.expand_path("Gemfile", __dir__)).strip
version = gemfile.lines.find { |line| line.include?('sqlite3') }
  .then { |sqlite3_line| sqlite3_line.strip.split(',').last.delete('"') }

gemfile(true) do
  source "https://rubygems.org"
  gem "rails", path: "."
  gem 'sqlite3', version
end

require "active_record"
require "minitest/autorun"
require "logger"

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :articles, force: true do |t|
    t.string :title
    t.string :category
  end
end

class Article < ActiveRecord::Base
end

puts
puts "ActiveRecord.version = #{ActiveRecord.version}"
puts

class BugTest < Minitest::Test
  def test_to_group_by_count_with_order
    article = Article.create(title: 'foo', category: 'foo')

    assert_equal ({"foo"=>1}), Article.group(:category).order('count_articles_id').count('`articles`.`id`')
  end
end

実際の手順

$ git clone https://github.com/rails/rails.git
$ cd rails
$ vim
(上記の再現コードを issue.rb として保存)
$ git bisect start v6.0.0.rc2 v5.2.3
$ git bisect run ruby issue.rb
.
.
.
(コーヒーでも飲みながら待つ)
.
.
.
Finished in 0.008043s, 124.3317 runs/s, 0.0000 assertions/s.
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
c9e4c848eeeb8999b778fa1ae52185ca5537fffe is the first bad commit
commit c9e4c848eeeb8999b778fa1ae52185ca5537fffe
Author: Ryuta Kamizono <kamipo@gmail.com>
Date:   Sat Apr 6 13:04:06 2019 +0900

    Don't repeat same expression in SELECT and GROUP BY clauses

    This refactors `execute_grouped_calculation` and slightly changes
    generated GROUP BY queries, since I'd not prefer to repeat same
    expression in SELECT and GROUP BY clauses.

    Before:

    ```
    SELECT COUNT(*) AS count_all, "topics"."author_name" AS topics_author_name, COALESCE(type, title) AS coalesce_type_title FROM "topics" GROUP BY "topics"."author_name", COALESCE(type, title)
    ```

    After:

    ```
    SELECT COUNT(*) AS count_all, "topics"."author_name" AS topics_author_name, COALESCE(type, title) AS coalesce_type_title FROM "topics" GROUP BY topics_author_name, coalesce_type_title
    ```

    Although we generally don't guarantee to support Arel node constructed
    by user itself, this also fixes #24207.

 .../lib/active_record/relation/calculations.rb     | 46 ++++++++++------------
 1 file changed, 20 insertions(+), 26 deletions(-)
bisect run success

なるほど、こうやってコミットを探すのか。

追記

bisect が終わった後に元のブランチに戻るには git bisect reset を実行する。