Commit message theo Conventional Commits và atomic commit Trung cấp
Thời gian đọc ước tính: 3 phút
Trang này trả lời: commit message viết thế nào cho cả người lẫn tool đọc được, và một commit nên chứa bao nhiêu thay đổi.
Cấu trúc Conventional Commits
Phần tiêu đề “Cấu trúc Conventional Commits”Theo Conventional Commits 1.0.0:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]Quy tắc chính của spec:
featbắt buộc cho tính năng mới,fixbắt buộc cho sửa bug. Type khác (docs,refactor,test,chore,perf,ci…) được phép, nhưng spec không định nghĩa nghĩa của chúng.- Breaking change:
!ngay trước dấu:(feat(api)!: ...), hoặc footerBREAKING CHANGE: <mô tả>. Token này phải viết hoa;BREAKING-CHANGElà đồng nghĩa. - Footer dạng
Token: valuehoặcToken #value; token dùng-thay khoảng trắng (Reviewed-by,Refs).
Từ commit tới SemVer
Phần tiêu đề “Từ commit tới SemVer”Đang tải diagram…
Breaking change đẩy lên MAJOR bất kể type: fix!: cũng là MAJOR.
Trước và sau
Phần tiêu đề “Trước và sau”Trước — đọc log không ra gì:
a1b2c3d fixd4e5f6a update order service9f8e7d6 wipSau — mỗi dòng trả lời “đổi gì, ở đâu”:
fix(order): làm tròn tổng tiền sau giảm giá theo VND
Trước đây giảm giá 10% cho đơn 199.999đ trả 179.999,1 và lưusố thập phân vào cột bigint, làm job đối soát lệch 1đ.Làm tròn xuống ở bước cuối, giữ nguyên số nguyên ở các bước giữa.
Refs: PAY-482Vì sao subject ≤ 50 ký tự
Phần tiêu đề “Vì sao subject ≤ 50 ký tự”| Nguồn | Khuyến nghị |
|---|---|
git commit docs (DISCUSSION) |
Dòng đầu “no more than 50 characters”, rồi một dòng trống, rồi phần mô tả |
| Pro Git | Body wrap khoảng 72 ký tự; thể mệnh lệnh (“Fix bug”, không phải “Fixed bug”) cho khớp message mà git merge, git revert tự sinh |
Dòng đầu là title dùng khắp nơi: git log --oneline, tiêu đề PR, email của format-patch, giao diện GitHub (cắt bớt khi quá dài). Body trả lời vì sao; diff đã nói cái gì.
Atomic commit: tách refactor khỏi thay đổi hành vi
Phần tiêu đề “Atomic commit: tách refactor khỏi thay đổi hành vi”Atomic commit = một thay đổi logic, tự build và pass test. Quy tắc quan trọng nhất: refactor (không đổi hành vi) và thay đổi hành vi nằm ở hai commit khác nhau.
Trước — một commit làm ba việc:
feat(order): hỗ trợ voucher theo phần trăm src/order/pricing.ts | 180 +++++---- (đổi tên biến, tách hàm, sửa logic) src/order/order.module.ts | 12 +- (đổi DI) package.json | 2 +- (nâng lodash)Sau — ba commit, mỗi commit review và revert độc lập:
chore(deps): nâng lodash 4.17.20 → 4.17.21refactor(order): tách tính giá ra PricingService # test cũ pass, không đổi hành vifeat(order): hỗ trợ voucher theo phần trăm # diff nhỏ, chỉ chứa logic mới| Việc | Commit gộp | Commit atomic |
|---|---|---|
| Review | Phải đọc lẫn rename với logic | Commit refactor chỉ cần hỏi “có đổi hành vi không?” — test cũ pass là bằng chứng |
| Voucher gây bug | revert mất luôn refactor và bản nâng lodash |
git revert đúng commit feat |
git bisect |
Chỉ ra commit 200 dòng | Chỉ ra commit 20 dòng |
Công cụ:
git add -p: stage từng hunk, tách một file thành nhiều commit.git commit --fixup=<sha>+git rebase -i --autosquash: sửa commit cũ trong PR (xem Branch, merge, rebase).
Tiếp theo: Branch, merge, rebase.