Commit message chuẩn: viết sao cho đội đọc hiểu

Commit message tệ khiến cả đội mất thời gian: không ai biết một dòng code đổi vì lý do gì, git log đầy “fix”, “update”, “wip”. Bài này chỉ ra cách viết commit message để người khác (và chính bạn sau 6 tháng) đọc là hiểu ngay tại sao thay đổi xảy ra, cùng cách giữ lịch sử Git sạch để việc review và truy vết lỗi nhanh hơn.

Vì sao commit message quan trọng hơn bạn nghĩ

Code trả lời câu hỏi “cái gì” và “như thế nào”. Diff đã cho thấy điều đó rồi. Thứ code không nói được là “tại sao”: vì sao bạn chọn cách này, vì sao phải thay đổi. Commit message là nơi duy nhất lưu lại lý do đó một cách gắn với từng dòng code cụ thể.

Khi một bug xuất hiện sau này, công cụ như git blamegit bisect chỉ hữu ích nếu mỗi commit nhỏ gọn và có message giải thích rõ. Một commit khổng lồ tên “update code” biến việc truy vết thành mò kim đáy bể.

Cấu trúc một commit message tốt

Quy ước phổ biến và được nhiều dự án mã nguồn mở dùng là chia message thành ba phần: dòng tiêu đề, thân, và chân.

Dòng tiêu đề (subject)

  • Ngắn, khoảng 50 ký tự, không quá 72.
  • Dùng thể mệnh lệnh: “Thêm validate email” thay vì “Đã thêm” hay “Thêm rồi”. Cách này khớp với message tự sinh của Git (ví dụ “Merge”, “Revert”).
  • Không kết thúc bằng dấu chấm.

Thân (body)

Cách dòng tiêu đề một dòng trống. Giải thích tại sao thay đổi, bối cảnh, và những đánh đổi. Đừng mô tả lại diff, hãy nói điều diff không nói được.

Chân (footer)

Tham chiếu issue, breaking change, hoặc đồng tác giả. Ví dụ Closes #142.

Conventional Commits: khi nào nên theo

Conventional Commits là quy ước thêm tiền tố loại vào tiêu đề, ví dụ feat:, fix:, refactor:, docs:. Ưu điểm: dễ tự động sinh changelog và đánh version. Nhược điểm: thêm ràng buộc, đội phải thống nhất và tuân thủ mới có giá trị.

Tình huống Nên dùng Conventional Commits?
Thư viện có versioning, cần changelog tự động Rất nên
Đội đông, nhiều repo, muốn thống nhất Nên
Dự án cá nhân nhỏ, ít commit Không bắt buộc

Ví dụ thực tế

Một message tệ:

fix bug

Cùng thay đổi đó, viết lại:

fix: chặn double-submit khi mạng chậm

Thân bài: “Nút đặt hàng không bị vô hiệu hóa sau lần bấm đầu, nên user bấm lại khi thấy trang chưa phản hồi, tạo hai đơn trùng. Thêm cờ khóa nút cho tới khi request kết thúc. Chưa xử lý trường hợp mất mạng giữa chừng, sẽ tách issue riêng.” Kèm Closes #88. Bất kỳ ai đọc cũng hiểu vấn đề, giải pháp, và phần còn bỏ ngỏ.

Lỗi thường gặp và cách sửa

  • Gộp nhiều thay đổi vào một commit. Sửa: mỗi commit một mục đích. Dùng git add -p để tách phần thay đổi.
  • Message chung chung như “update”, “fix”. Sửa: luôn nêu đối tượng cụ thể và lý do.
  • Chỉ mô tả lại diff. Sửa: viết phần “tại sao”, để diff tự nói phần “cái gì”.
  • Commit code hỏng, chưa build được. Sửa: mỗi commit nên là một trạng thái chạy được, giúp git bisect hoạt động.
  • Sợ lịch sử xấu nên không dám commit nhỏ. Sửa: commit thoải mái trên nhánh, rồi dùng rebase -i dọn lại trước khi merge.

Checklist trước khi commit

  • Commit này chỉ làm một việc?
  • Tiêu đề dưới 72 ký tự, thể mệnh lệnh?
  • Nếu thay đổi không hiển nhiên, đã viết thân giải thích “tại sao”?
  • Code trong commit này build và chạy được?
  • Đã tham chiếu issue liên quan nếu có?

Kết luận

Commit message tốt là món quà bạn tặng đội và tặng chính mình trong tương lai. Bước tiếp theo cụ thể: chọn một quy ước (mệnh lệnh + tùy chọn Conventional Commits), viết ra thành một dòng trong README của repo, và áp dụng ngay từ commit kế tiếp.

Câu hỏi thường gặp

Commit nhỏ hay commit lớn tốt hơn?

Commit nhỏ, mỗi cái một mục đích, gần như luôn tốt hơn cho review và truy vết lỗi. Bạn vẫn có thể gộp lại bằng rebase nếu muốn lịch sử gọn khi merge.

Có nên viết commit message bằng tiếng Việt?

Tùy đội. Nếu cả đội và tương lai đều là người Việt thì hoàn toàn ổn. Với dự án mã nguồn mở hoặc đội đa quốc gia, tiếng Anh phổ biến hơn. Quan trọng là thống nhất một ngôn ngữ.

Rebase để sửa lịch sử có nguy hiểm không?

Chỉ nguy hiểm khi rebase nhánh đã đẩy chung và người khác đang dùng. Trên nhánh riêng của bạn thì rebase để dọn dẹp là an toàn và được khuyến khích.

Có cần công cụ ép định dạng commit không?

Với đội lớn, hook như commit-msg giúp giữ kỷ luật. Với đội nhỏ tin tưởng nhau, một thỏa thuận rõ ràng thường đủ. Đừng thêm công cụ nếu chưa thấy đau.

Tham khảo

  • Tài liệu chính thức của Git về git commitgit rebase (git-scm.com).
  • Conventional Commits (conventionalcommits.org).

Similar Posts