Cách viết Git Commit Message | Giới hạn ký tự và phương pháp tốt nhất

8 phút đọc

Git commit message là manh mối thiết yếu để hiểu lịch sử thay đổi của codebase. Những message được viết tốt cải thiện đáng kể hiệu quả review code và điều tra lỗi sau nhiều tháng. Ngược lại, những message mơ hồ trở thành nợ kỹ thuật kéo giảm năng suất của cả nhóm. Bài viết này đề cập đến hướng dẫn số ký tự và các phương pháp tốt nhất thực tế cho commit message. Để có cái nhìn rộng hơn về quy trình làm việc với Git, sách về quản lý phiên bản Git trên Amazon là điểm khởi đầu vững chắc. Sử dụng Bộ đếm ký tự để kiểm tra độ dài message của bạn.

Những sự thật bất ngờ về Commit Message

Quy ước "tiêu đề 50 ký tự, xuống dòng nội dung 72 ký tự" bắt nguồn từ thời kỳ email. Người tạo ra Git, Linus Torvalds, đã kế thừa thực tiễn gửi patch qua email trong quá trình phát triển nhân Linux. Các ứng dụng email thường hiển thị 80 cột, và sau khi trừ đi ký hiệu trích dẫn và thụt lề, 72 ký tự là độ rộng nội dung tối ưu.

Theo dữ liệu của GitHub, độ dài trung bình của commit message trong các dự án mã nguồn mở ước tính khoảng 40–50 ký tự. Tuy nhiên, chất lượng message tương quan với sức khỏe dự án — những dự án có message rất ngắn (dưới 10 ký tự) thường có hiệu quả sửa lỗi thấp hơn.

Phân tích commit message trên các dự án OSS lớn cho thấy xu hướng rõ ràng về độ dài dòng tiêu đề. Nhân Linux có độ dài tiêu đề trung vị khoảng 55 ký tự, thường xuyên vượt quá quy tắc 50 ký tự, trong khi các dự án áp dụng Conventional Commits — như Angular và Vue.js — duy trì trung vị khoảng 45 ký tự. Vì các prefix như feat: hoặc fix: chiếm 5–10 ký tự, phần mô tả thực tế bị giới hạn ở 35–40 ký tự, điều này tự nhiên khuyến khích viết message ngắn gọn.

Nguồn gốc và cơ sở kỹ thuật của quy tắc 50/72

Quy tắc 50/72 bắt nguồn từ độ rộng terminal 80 cột. Đầu ra mặc định của git log thêm commit hash (7 ký tự) và một khoảng trắng vào đầu mỗi dòng, để lại khoảng 72 ký tự cho tiêu đề. Với git log --oneline, hash cộng khoảng trắng chiếm 8 ký tự, khiến 72 trở thành độ rộng hiển thị hiệu quả. Giới hạn 50 ký tự được khuyến nghị đóng vai trò như "giới hạn mềm" cung cấp khoảng trống thoải mái trong ranh giới cứng 72 ký tự này.

Việc xuống dòng nội dung ở 72 ký tự cũng có cơ sở rõ ràng. Các patch được tạo bởi git format-patch được gửi dưới dạng email, và các phản hồi trên mailing list thêm > (2 ký tự) để trích dẫn. Với hai cấp trích dẫn (> > = 4 ký tự) cộng 4 ký tự thụt lề, 72 ký tự là tối đa vừa vặn trong hiển thị 80 cột. Phép tính này là nền tảng của quy tắc 72 ký tự vẫn được sử dụng rộng rãi ngày nay.

Cấu trúc cơ bản và hướng dẫn số ký tự

Git commit message tuân theo cấu trúc hai phần: dòng tiêu đề và nội dung, được phân tách bằng một dòng trống. Cấu trúc này phù hợp với cách git log --oneline và danh sách commit của GitHub chỉ hiển thị tiêu đề.

Phần tửHướng dẫn ký tựLý do
Dòng tiêu đề50 ký tự trở xuốngHiển thị không bị cắt trong chế độ xem danh sách của GitHub
Tiêu đề (giới hạn cứng)72 ký tự trở xuốngVượt quá 72, GitHub thêm dấu ba chấm (...)
Độ rộng dòng nội dungXuống dòng ở 72 ký tựVừa vặn với độ rộng terminal tiêu chuẩn (80 cột) với lề thụt
Tổng nội dungKhông giới hạnThêm giải thích chi tiết khi cần

GitHub và GitLab khác nhau ở vị trí cắt dòng tiêu đề. Danh sách commit của GitHub cắt ở khoảng 72 ký tự, nhưng trang chính của repository cắt ở khoảng 50 ký tự. Danh sách commit của GitLab hiển thị tối đa khoảng 80 ký tự, cho nhiều không gian hơn GitHub một chút. Để đảm bảo hiển thị nhất quán trên cả hai nền tảng, giữ tiêu đề dưới 50 ký tự là cách tiếp cận an toàn nhất.

Ký tự đa byte trong Commit Message

Khi viết commit message bằng các ngôn ngữ có ký tự đa byte (như tiếng Nhật, tiếng Trung hoặc tiếng Hàn), sự khác biệt giữa số ký tự và số byte trở thành mối quan tâm đáng kể. Git xử lý nội bộ các chuỗi dưới dạng UTF-8, nên một ký tự CJK đơn lẻ chiếm 3 byte. GitHub xác định việc cắt tiêu đề dựa trên độ rộng hiển thị (số cột) thay vì số byte, và mỗi ký tự toàn chiều rộng chiếm 2 cột. Điều này có nghĩa là tối đa 25 ký tự toàn chiều rộng vừa vặn trong độ rộng hiển thị 50 cột.

Hiển thị git log trong terminal cũng gặp vấn đề tính toán độ rộng với ký tự đa byte. Hầu hết các trình giả lập terminal hiển thị ký tự toàn chiều rộng ở 2 cột dựa trên thuộc tính East Asian Width, nhưng một số môi trường (đặc biệt là Command Prompt Windows cũ) tính sai độ rộng, gây ra đầu ra bị lệch. Nếu các cột không thẳng hàng trong git log --oneline, hãy kiểm tra cài đặt độ rộng ký tự của terminal.

Đối với các nhóm sử dụng commit message không phải ASCII, cách tiếp cận kết hợp — prefix tiếng Anh với mô tả bằng ngôn ngữ bản địa — hoạt động tốt trên thực tế. Ví dụ, fix(auth): ログイン時のセッション復元を修正 vẫn giữ được khả năng lọc theo loại với git log --oneline --grep="^fix" trong khi vẫn dễ đọc cho người bản ngữ.

Conventional Commits và cách sử dụng Prefix

Conventional Commits là một đặc tả mang lại cấu trúc nhất quán cho commit message. Thêm prefix loại vào đầu mỗi message giúp nhận biết ngay bản chất của thay đổi và cho phép tự động tạo CHANGELOG cùng quản lý phiên bản ngữ nghĩa.

Triết lý thiết kế đằng sau đặc tả này tập trung vào tích hợp tự động với Semantic Versioning (SemVer). Commit feat tương ứng với tăng phiên bản MINOR, fix tương ứng với tăng PATCH, và các commit chứa footer BREAKING CHANGE báo hiệu tăng phiên bản MAJOR. Ánh xạ này cho phép các công cụ như semantic-releasestandard-version tự động xác định số phiên bản từ lịch sử commit.

Định dạng cơ bản là <type>(<scope>): <description>. Scope là tùy chọn và chỉ ra module hoặc component bị ảnh hưởng.

PrefixMục đíchVí dụ
featTính năng mớifeat(auth): add OAuth2 login support
fixSửa lỗifix(api): resolve null pointer in user endpoint
docsThay đổi tài liệudocs: update API reference for v2
styleKiểu code (không thay đổi hành vi)style: fix indentation in config file
refactorTái cấu trúcrefactor(db): simplify query builder logic
testThêm hoặc sửa testtest: add unit tests for payment module
choreThay đổi build hoặc công cụchore: upgrade webpack to v5
perfCải thiện hiệu suấtperf(search): add index for full-text query
ciCấu hình CI/CDci: add GitHub Actions workflow

Tại sao nên dùng thể mệnh lệnh

Khuyến nghị sử dụng thể mệnh lệnh trong commit message tiếng Anh bắt nguồn từ chính thiết kế của Git. Các message mà Git tự động tạo ra — Merge branch 'feature', Revert "Add login form", Cherry-pick from abc1234 — đều ở thể mệnh lệnh. Sử dụng cùng phong cách này trong message do người dùng viết tạo ra giọng văn thống nhất trong toàn bộ đầu ra git log.

Message ở thể mệnh lệnh đọc như mô tả về điều xảy ra khi commit được áp dụng. Add user authentication có nghĩa là "commit này thêm xác thực người dùng," trực tiếp diễn đạt hiệu quả của commit. Ngược lại, Added user authentication (thì quá khứ) đọc như báo cáo về việc đã làm — một bản ghi công việc thay vì mô tả hiệu quả của commit.

Khi phân vân, hãy thử chèn message của bạn vào câu "If applied, this commit will ___." If applied, this commit will add user authentication đọc tự nhiên, trong khi If applied, this commit will added user authentication sai ngữ pháp.

Ví dụ commit message tốt và xấu

Ví dụ xấuVấn đềVí dụ tốt
fix bugLỗi nào?fix(cart): prevent duplicate items on rapid click
updateCập nhật gì?docs: add setup instructions for local dev
WIPCông việc dang dở còn trong lịch sửfeat(ui): add skeleton loader for product list
asdfghChuỗi vô nghĩarefactor: extract validation logic into helper
Fixed the thing that was broken...Dài dòng, vượt quá 50 ký tựfix(auth): restore session after token refresh

Thiết kế message cho Squash Merge và Revert

Khi sử dụng squash merge, nhiều commit được gộp thành một, nên thiết kế message khác với commit thông thường. Squash merge mặc định của GitHub sử dụng tiêu đề pull request làm tiêu đề và liệt kê các commit message riêng lẻ dưới dạng danh sách trong nội dung. Message tự động tạo này thường dài dòng. Đối với squash merge, hiệu quả hơn khi sử dụng mô tả pull request làm nội dung, tóm tắt ngắn gọn mục đích và phạm vi của thay đổi.

Đối với revert commit, quy ước là sử dụng định dạng tự động của Git: Revert "<original subject>". Trong nội dung, bao gồm hash commit gốc (This reverts commit <hash>.) cùng với lý do revert. Nếu không có lý do, sẽ không thể hiểu "tại sao nó bị revert" khi truy vết lịch sử sau này. Khi revert nhiều commit cùng lúc, hãy nêu rõ phạm vi — chẳng hạn revert: undo feature X (commits abc..def) — để việc theo dõi lịch sử dễ dàng hơn.

Quy ước Commit Message trong nhóm

Trong khi dự án cá nhân cho phép linh hoạt, phát triển theo nhóm đòi hỏi quy tắc thống nhất. Các thực tiễn sau giúp duy trì chất lượng message trong toàn tổ chức:

Đây là cách thiết lập thực tế kết hợp commitlint và husky. Cài đặt với npm install --save-dev @commitlint/cli @commitlint/config-conventional husky, sau đó tạo commitlint.config.js tại thư mục gốc dự án với module.exports = { extends: ['@commitlint/config-conventional'] };. Khởi tạo husky với npx husky init, và thêm npx --no -- commitlint --edit $1 vào .husky/commit-msg. Điều này tự động xác thực mọi commit message khi commit. Để tìm hiểu thêm về thực tiễn Git cấp nhóm, sách hướng dẫn thực tiễn nhóm phát triển phần mềm cung cấp các quy trình đã được chứng minh.

Quy tắc quá nghiêm ngặt có thể làm chậm quá trình phát triển, vì vậy hãy áp dụng dần dần. Bắt đầu với chuẩn hóa prefix, sau đó giới thiệu commitlint khi nhóm đã quen.

Commit Message do AI tạo: Lợi ích và lưu ý

GitHub Copilot và các tiện ích mở rộng editor khác nhau cung cấp tính năng tự động tạo commit message, giảm đáng kể công sức viết message. Các công cụ này phân tích diff để tóm tắt những gì đã thay đổi, và độ chính xác trong việc mô tả "cái gì đã thay đổi" thường khá cao.

Tuy nhiên, tự động tạo có những hạn chế rõ ràng. Điểm yếu lớn nhất là không thể suy luận "tại sao thay đổi là cần thiết." Code diff không tiết lộ động cơ hay bối cảnh kinh doanh đằng sau thay đổi, nên phần "Tại sao" thuộc về nội dung phải do con người cung cấp. Ngoài ra, message tự động tạo thường dài dòng và hay vượt quá giới hạn 50 ký tự cho tiêu đề. Thay vì sử dụng đầu ra tự động nguyên trạng, hãy luôn xem xét, cắt bỏ chi tiết không cần thiết và rút gọn thành message ngắn gọn.

Kết luận

Quy ước được chấp nhận rộng rãi cho Git commit message là dòng tiêu đề 50 ký tự trở xuống với nội dung xuống dòng ở 72 ký tự. Những con số này bắt nguồn từ độ rộng terminal 80 cột và quy ước trích dẫn email, và chúng phù hợp với hành vi hiển thị của GitHub và GitLab. Prefix Conventional Commits giúp nhận biết ngay loại thay đổi và hỗ trợ tự động tạo CHANGELOG. Khi viết message với ký tự đa byte, hãy lưu ý độ rộng hiển thị — ký tự toàn chiều rộng chiếm 2 cột mỗi ký tự, nên hãy nhắm khoảng 25 ký tự cho tiêu đề. Message tốt truyền đạt ngắn gọn "cái gì" và "tại sao," trong khi message xấu thì mơ hồ và thiếu thông tin. Sử dụng Bộ đếm ký tự để kiểm tra độ dài commit message của bạn.