Git blame và git bisect: truy tìm nguồn gốc của dòng code và của lỗi

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Một chức năng đang chạy tốt tuần trước bỗng hỏng, mà từ đó có hàng chục commit của nhiều người. Hoặc bạn thấy một đoạn code kỳ lạ và muốn biết tại sao nó lại ở đó. Git có sẵn hai công cụ rất mạnh cho các tình huống này: git blame và git bisect. Bài này hướng dẫn cách dùng hiệu quả.

git blame: ai sửa dòng này, khi nào, vì sao?

Dù tên gọi nghe như "đổ lỗi", mục đích thực sự của git blame là tìm ngữ cảnh: dòng code này xuất hiện trong commit nào, do ai, kèm thông điệp gì. Từ đó bạn hiểu lý do thay vì đoán.

git blame src/order.js^a1b2c3d (An   2025-01-10 1) function calculateTotal(items) {7f8e9d0e (Bình 2025-02-14 2)   if (items.length === 0) return 0;3c4d5e6f (An   2025-02-20 3)   return items.reduce(...);}

Mỗi dòng đi kèm mã commit, tác giả và ngày. Từ mã commit, xem chi tiết bằng:

git show 7f8e9d0e

Bạn sẽ đọc được toàn bộ thay đổi và thông điệp commit giải thích lý do thêm dòng kiểm tra rỗng.

Mẹo dùng blame hiệu quả

  • Chỉ xem một đoạn: git blame -L 10,30 src/order.js chỉ hiện dòng 10 đến 30.
  • Bỏ qua thay đổi khoảng trắng: thêm -w để commit chỉ chỉnh định dạng không che mất tác giả thật.
  • Phát hiện code được di chuyển hoặc sao chép: dùng -M (di chuyển trong file) và -C (từ file khác).
  • Bỏ qua commit định dạng hàng loạt: dùng --ignore-revs-file .git-blame-ignore-revs.
  • Dùng giao diện: VS Code với extension như GitLens hiển thị thông tin blame ngay cạnh mỗi dòng, các nền tảng như GitHub có nút Blame trên từng file.
  • Đi sâu hơn: sau khi biết commit, hãy xem tiếp pull request hoặc issue liên kết để hiểu bối cảnh.

Và hãy nhớ mục tiêu là hiểu lý do, không phải tìm người để trách. Nhiều dòng code "kỳ lạ" chỉ là hệ quả của yêu cầu thay đổi hoặc ràng buộc lúc đó.

git log để tìm lịch sử một đoạn code

# Lịch sử của một filegit log --oneline -- src/order.js# Lịch sử của một hàm hoặc dòng cụ thểgit log -L :calculateTotal:src/order.js# Tìm commit có thay đổi liên quan tới một chuỗigit log -S"calculateTotal" --oneline

Tùy chọn -S (còn gọi "pickaxe") rất hữu ích để tìm commit thêm hoặc xóa một chuỗi cụ thể, ví dụ khi bạn muốn biết khi nào một hàm bị xóa.

git bisect: tìm commit gây lỗi bằng tìm kiếm nhị phân

Khi biết rằng "bản cũ chạy đúng, bản hiện tại bị lỗi" nhưng không biết commit nào gây ra, bisect giúp bạn khoanh vùng nhanh. Nó dùng thuật toán tìm kiếm nhị phân: chia đôi khoảng commit nghi ngờ, bạn kiểm tra bản ở giữa tốt hay xấu, rồi tiếp tục chia đôi. Với 1000 commit, chỉ cần khoảng 10 lần kiểm tra.

Các bước thực hiện

  1. Bắt đầu: git bisect start
  2. Đánh dấu bản hiện tại là lỗi: git bisect bad
  3. Đánh dấu một commit cũ từng chạy đúng: git bisect good v1.2.0 (hoặc mã commit)
  4. Git checkout một commit ở giữa. Bạn chạy ứng dụng hoặc test để kiểm tra, rồi báo kết quả: git bisect good nếu chạy đúng hoặc git bisect bad nếu còn lỗi.
  5. Lặp lại đến khi Git thông báo commit đầu tiên gây lỗi.
  6. Kết thúc và quay về nhánh ban đầu: git bisect reset

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

Nếu bạn có thể viết một lệnh trả về mã 0 khi đúng và khác 0 khi sai (một test chẳng hạn), Git tự động làm hết:

git bisect start HEAD v1.2.0git bisect run npm test -- --testNamePattern="calculateTotal"

Git sẽ tự checkout, chạy lệnh, phân loại và chia đôi cho tới khi tìm ra commit thủ phạm. Đây là cách cực kỳ hiệu quả khi có test tái hiện lỗi. Có thể viết test mới chỉ để tái hiện lỗi và dùng nó với bisect.

Lưu ý khi bisect

  • Cần một cách tái hiện lỗi ổn định và nhanh. Lỗi chập chờn sẽ làm kết quả sai.
  • Nếu commit ở giữa không build được, dùng git bisect skip để bỏ qua.
  • Có thể cần cài lại phụ thuộc hoặc migrate lại dữ liệu khi chuyển qua các commit khác nhau.
  • Commit nhỏ, độc lập, mỗi commit đều chạy được (như đã nói ở các bài về commit) giúp bisect chính xác và dễ hiểu.
  • Làm việc trong một thư mục sạch (đã commit hoặc stash thay đổi hiện có) để tránh xung đột khi Git chuyển commit.

Kết hợp blame và bisect trong thực tế

  1. Dùng bisect để tìm commit đầu tiên gây lỗi.
  2. Đọc git show của commit đó để hiểu thay đổi.
  3. Dùng blame và thông điệp commit, pull request liên kết để biết mục đích ban đầu.
  4. Sửa lỗi sao cho không phá vỡ mục đích thật của thay đổi cũ, và thêm test để lỗi không quay lại.

Kết luận

Lịch sử Git là kho thông tin quý giá nếu bạn biết khai thác. git blame cho bạn ngữ cảnh của từng dòng, git bisect giúp tìm ra commit gây lỗi trong vài bước thay vì đọc cả trăm commit. Hãy thử bisect trên một repo cá nhân để làm quen trước khi cần dùng thật.

Nếu bạn muốn luyện Git và kỹ năng debug cho dự án nhóm, hãy ghé qua codebem.com để chọn khóa học phù hợp.

author_photo
Nguyễn Đình Cường

0 comment