Git Bisect: Tìm commit gây bug trong 5 phút

Git Bisect là gì?

Git Bisect là lệnh binary search trên Git history — tự động tìm commit đầu tiên gây bug trong O(log n) thay vì O(n). Thay vì checkout 100 commit thủ công, bạn chỉ cần test ~7 commit để tìm ra thủ phạm.

Đây là công cụ tiết kiệm thời gian nhất của Git — đặc biệt khi bạn debug regression trên codebase lớn, không nhớ bug xuất hiện từ đâu.

Git bisect workflow showing binary search on commit history

Bisect workflow cơ bản

Quy trình 4 bước:

  1. git bisect start — khởi động bisect session
  2. git bisect bad — đánh dấu commit hiện tại (có bug)
  3. git bisect good COMMIT_HASH — đánh dấu commit gần nhất biết chắc không có bug
  4. Git tự động checkout giữa 2 mốc — bạn test, gõ git bisect good hoặc git bisect bad — lặp lại cho tới khi tìm ra commit gây bug.

Ví dụ thực tế:

# Bug xuất hiện giữa v1.2.0 và v1.3.0
git bisect start
git bisect bad                    # HEAD hiện tại có bug
git bisect good v1.2.0            # v1.2.0 chạy ổn

# Git checkout sang commit giữa 2 version
Bisecting: 23 revisions left to test after this

# Test app, thấy bug vẫn còn → đánh dấu bad
git bisect bad

# Git checkout sang commit giữa remaining range
Bisecting: 11 revisions left to test after this

# Test app, thấy bug đã mất → đánh dấu good
git bisect good

# Lặp lại ~7 lần → Git tìm ra commit gây bug
abc1234 is the first bad commit

Tự động hóa với run script

Nếu có test script reproduce bug được, dùng git bisect run — Git tự chạy script, tự đánh dấu good/bad, không cần can thiệp:

git bisect start
git bisect bad HEAD
git bisect good v1.2.0
git bisect run ./test_regression.sh

# test_regression.sh trả 0 = good, 1-127 = bad, 125-127 = skip
#!/bin/bash
xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15'
exit $?

Script kiểm tra exit code: nếu test pass → trả 0, Git đánh dấu good. Nếu test fail → trả 1, Git đánh dấu bad. Bisect chạy hoàn toàn tự động.

Terminal showing git bisect run output

Skip và abort

Nếu commit không build được hoặc không thể test:

  • git bisect skip — bỏ qua commit hiện tại, Git chọn commit khác
  • git bisect reset — thoát bisect, quay về HEAD ban đầu

Nếu bạn đánh dấu nhầm good/bad, dùng git bisect log xem lịch sử, git bisect replay FILE apply lại với lần chọn đúng.

Bisect với multiple branches

Khi merge nhiều nhánh, Git history có thể không linear. Dùng git bisect --first-parent để chỉ walk trên first-parent chain — tức là merge commits, bỏ qua commits từ feature branch:

git bisect start --first-parent
git bisect bad main
git bisect good v1.2.0

Tiện dụng khi bug do conflict resolution trong merge commit gây ra — bạn không cần test từng commit nhỏ trong feature branch.

Kết hợp với blame và log

Bisect tìm commit gây bug. Để tìm dòng code thay đổi:

# Sau khi bisect xong
git show abc1234 --stat              # xem file thay đổi
git blame -L 120,150 app/Model.swift # xem ai sửa dòng 120-150
git log -p abc1234                   # xem full patch commit gây bug

Thông thường, commit gây bug có message rõ ràng (nếu team tuân thủ commit convention) — đọc message thường đủ để hiểu intent, git show để xem exact change.

Trường hợp dùng Bisect thường xuyên

  • Regression không có changelog: Bug xuất hiện đột ngột, không biết ai push gì gây ra.
  • Performance drop: App chạy chậm hơn sau release, cần tìm commit thay đổi algorithm/database query.
  • UI break: Layout vỡ sau merge, cần tìm xem conflict resolution sai ở đâu.
  • Memory leak mới: Leak xuất hiện giữa 2 version — bisect + Instruments automation.

Tài liệu tham khảo

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

Tailscale: Mesh VPN zero-config thay thế WireGuard truyền thống

Giới thiệu Tailscale: Mesh VPN zero-config thay thế WireGuard truyền thống Tailscale là một mesh VPN hiện đại được xây dựng trên nền tảng WireGuard® protocol, mang lại trải nghiệm…

Xem thêm

Neovim: Biến trình biến thành IDE mạnh mẻ với Lua và các plugin

Neovim là bản fork hiện đại của editor kinh điển Vim, được xây dựng lại với trọng tâm extensibility và usability. Xây dựng trên nền LuaJIT, Neovim hỗ trợ remote…

Xem thêm

Portainer: Quản lý Docker Container qua Giao diện Web

Docker container đã trở thành công cụ chuẩn cho deployment, nhưng quản lý hàng chục container qua dòng lệnh cực kỳ tẻ nhạt. Tạo network, inspect log, restart container, xem…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất