Bisect: truy vết commit gây bug bằng binary search
Bisect: Tracking Down the Buggy Commit with Binary Search
Bug mới xuất hiện nhưng bạn không biết commit nào gây ra, mà nhánh có hàng trăm commit? Dò từng cái thì quá lâu. Bisect dùng tìm kiếm nhị phân binary search để khoanh vùng commit lỗi chỉ trong vài bước.
Ý tưởng: binary search trên lịch sử
Bạn biết một commit cũ chạy tốt (good) và commit hiện tại bị lỗi (bad). Bisect liên tục checkout commit ở giữa khoảng đó, hỏi bạn good hay bad, rồi loại bỏ một nửa. Với 1000 commit, bạn chỉ cần kiểm tra khoảng 10 lần (log2 của 1000).
Quy trình thủ công
# Bắt đầu phiên bisect
git bisect start
# Đánh dấu commit hiện tại là lỗi
git bisect bad
# Đánh dấu một commit cũ đã biết là tốt
git bisect good v1.2.0
Git tự checkout commit ở giữa. Bạn build/test rồi báo kết quả:
# Nếu commit này còn tốt:
git bisect good
# Nếu commit này đã lỗi:
git bisect bad
Lặp lại cho tới khi Git in ra: <hash> is the first bad commit. Khi xong:
# Trả HEAD về trạng thái ban đầu
git bisect reset
Tự động hóa với bisect run
Nếu bạn có một script/test trả về exit code 0 khi tốt, khác 0 khi lỗi, hãy để Git tự chạy toàn bộ:
git bisect start HEAD v1.2.0 # bad good gộp một dòng
git bisect run ./test-bug.sh
Bisect run sẽ tự checkout, chạy script và phân loại good/bad ở mỗi bước cho tới khi tìm ra thủ phạm — không cần bạn ngồi canh.
# Ví dụ test-bug.sh
#!/bin/bash
npm run build || exit 125 # 125 = bỏ qua commit không build được
npm test -- --grep "login" # exit code quyết định good/bad
Mã 125 để bỏ qua commit
Trong script bisect, trả về exit code 125 cho những commit không thể test được (build hỏng, thiếu dependency). Git sẽ bỏ qua chúng thay vì tính là good/bad, giúp kết quả chính xác.
Đừng quên bisect reset
Trong lúc bisect, bạn đang ở trạng thái detached HEAD trên các commit cũ. Luôn chạy git bisect reset khi xong để quay về nhánh ban đầu, tránh commit nhầm vào trạng thái rời.
Trọng tâm thi
bisect = tìm kiếm nhị phân để tìm first bad commit. Cần một mốc good và một mốc bad; mỗi bước loại nửa số commit. git bisect run <script> tự động hóa bằng exit code (0 = good, khác 0 = bad, 125 = bỏ qua).
Tóm tắt
git bisectdùng binary search để tìm commit đầu tiên gây bug giữa một mốc good và một mốc bad.- Quy trình:
bisect start→bisect bad→bisect good <ref>→ trả lời good/bad mỗi bước →bisect reset. - Mỗi bước loại bỏ một nửa lịch sử, nên cực nhanh với repo lớn.
git bisect run <script>tự động hóa bằng exit code: 0 = good, khác 0 = bad, 125 = bỏ qua commit.- Luôn
git bisect resetđể rời detached HEAD và về nhánh ban đầu.