Skip to content

Instantly share code, notes, and snippets.

@NewAlexandria
Last active November 12, 2023 18:52
Show Gist options
  • Save NewAlexandria/68692dda4cde7a861337dc4e5b338d14 to your computer and use it in GitHub Desktop.
Save NewAlexandria/68692dda4cde7a861337dc4e5b338d14 to your computer and use it in GitHub Desktop.
Bisect class to decompose the diff history to be per-file
# Ruby class for automating 'git bisect' with Rails tests
class BisectTest
def initialize(files_to_test: , last_good_commit: )
@files_to_test = files_to_test.is_a?(Array) ? files_to_test : [files_to_test]
@last_good_commit = last_good_commit
end
# Function to run the test suite and return true if the test passed, false if it failed
def test_command
"bundle exec rails test #{@files_to_test.join(' ')}"
end
def run_test(commit)
results = @files_to_test.map { |file| `git checkout #{commit} && bundle exec rails test #{file}` }
rr = results.select { |res| res.include?("0 failures, 0 errors") }
rr.empty? ? nil : rr
end
# Start the 'git bisect' process
def start_bisect
system("git bisect start")
system("git bisect bad HEAD")
system("git bisect good #{@last_good_commit}")
end
# Run the 'git bisect' process
def run_bisect
start_bisect
# system("git bisect run") do |commit|
# exit 1 if run_test(commit)
# exit 0
# end
system("git bisect run #{test_command}")
end
def create_bisect_prism_branch
# system("git checkout #{@branch_name} #{@last_good_commit}")
system("git checkout -b #{bisecting_branch_name}")
end
def changed_files
# `git diff --name-only HEAD #{@last_good_commit}`.split("\n").map(&:strip)
`git diff --name-only`.split("\n").map(&:strip)
end
def bisecting_branch_name(branch_name: @branch_name, prefix: 'bisecting')
bp = branch_name.split('/')
bp = bp.size > 1 ? branch_name.tap{|ps| ps[0] = prefix } : bp.unshift(prefix)
bp.join('/')
end
def bisect_prism
`git reset #{@last_good_commit}`
create_bisect_prism_branch
changed_files.map do |file|
# staged_chunks = `git diff -U0 --staged -- #{file} | grep -e '^\@' | sed 's/^\@.*\\+\([0-9]\\+\\),\\([0-9]\\+\\)/\\1,\\2/'`.split("\n")
# staged_chunks.each_with_index do |chunk, index|
puts "🗂️ #{file}"
end
[
`git add #{file}`,
`git commit -m "git bisect prism: #{file}"`
]
end
end
end
__END__
# Example usage:
files_to_test = "test/models/files_to_test.rb"
last_good_commit = "abcdef123" # Replace with a specific commit hash
bisect = BisectTest.new(files_to_test, last_good_commit)
bisect.run_bisect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment