Cập nhật lần cuối:

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. Sử dụng Bộ đếm ký tự để kiểm tra độ dài message của bạn.

Hướng dẫn số ký tự có tính bắt buộc đến đâu

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.

Bản thân Git không đặt giới hạn nào cho độ dài của commit message. Bạn có thể viết một dòng tiêu đề dài hàng trăm ký tự mà không nhận được lỗi hay cảnh báo nào. Nói cách khác, 50 và 72 không phải là quy tắc do công cụ cưỡng chế, mà là hướng dẫn vận hành sinh ra từ môi trường hiển thị. Cái thực sự mất đi khi vượt quá là khả năng đọc: tiêu đề bị cắt trong các danh sách, còn nội dung bị xuống dòng ở những chỗ không mong muốn.

Một điểm cần tính trước khi áp dụng Conventional Commits là các prefix cũng tiêu tốn ngân sách ký tự của dòng tiêu đề. feat: chiếm 5 ký tự, và khi thêm scope như fix(auth): thì phần đầu dòng có thể vượt 10 ký tự. Nếu bạn nhắm tới mốc 50 ký tự, phần mô tả thực sự chỉ còn khoảng 40 ký tự trở xuống, nên hãy trừ sẵn phần prefix khi cân nhắc độ dài.

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. Ở định dạng mặc định (medium) của git log, commit hash nằm trên một dòng riêng và nội dung message được thụt lề 4 khoảng trắng, nên con số 72 không đến từ đó. Nơi độ rộng thực sự bị bó lại là git log --oneline: hash viết tắt 7 ký tự cộng một khoảng trắng chiếm 8 cột ở đầu dòng, để lại khoảng 72 cột cho tiêu đề trên terminal 80 cột. Giới hạn 50 ký tự được khuyến nghị đóng vai trò như "giới hạn mềm" chừa khoảng trống thoải mái bên trong ranh giới 72 cộ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. Cách tính này được chia sẻ rộng rãi như lời giải thích cho con số 72 (bản thân hướng dẫn của Git không quy định độ rộng dòng nội dung).

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ốngHướng dẫn chính thức của Git (phần DISCUSSION của git commit) khuyến nghị dưới 50 ký tự
Tiêu đề (giới hạn thực dụng)72 ký tự trở xuốngVừa đủ để git log --oneline không bị xuống dòng trên terminal 80 cột
Độ 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

Vị trí cắt dòng tiêu đề khác nhau tùy từng màn hình và từng dịch vụ, và các nền tảng không công bố con số cụ thể. Vị trí đó còn thay đổi theo bề rộng cửa sổ và theo mỗi lần cập nhật giao diện, nên việc chỉnh tiêu đề để khớp chính xác một mốc ký tự là công sức không tương xứng với lợi ích thu được. Cách thực tế hơn là giữ tiêu đề gọn dưới 50 ký tự, mức đủ để đọc được trọn vẹn ở gần như mọi nơi.

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-release và standard-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' khi merge và Revert "Add login form" khi hoàn tác - đề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. Với squash merge trên GitHub, tiêu đề pull request thường được dùng làm dòng tiêu đề và các commit message riêng lẻ được liệt kê thành danh sách trong nội dung, tuy hành vi này có thể thay đổi trong cài đặt của repository. 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.

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 là hướng dẫn vận hành chứ không phải giới hạn kỹ thuật - bản thân Git không hạn chế độ dài message. 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.

Chia sẻ bài viết này