[Git] Làm sao để viết những Commit Message tốt (P1)
git commit -m "feat: add meaningful commit messages to your workflow"
Các commit message được viết một cách chuyên nghiệp có thể giúp bạn và team tiết kiệm được cả khối thời gian để trả lời cho các câu hỏi:
- Tại sao người anh em thiện lành này lại viết đoạn code như này? (@_@)
- Logic của đoạn code này là sao ta? Tại sao lại có các điều kiện này? Thời gian đó nên được sử dụng để hoàn thành công việc có phải tốt hơn không?
Tại sao một commit message chất lượng lại quan trọng đến thế?
Commit message thực sự là một cách giao tiếp giữa các thành viên trong team.
Hãy thử đặt mình vào tình huống như sau:
Có một cái bug "tự nhiên" xuất hiện trong ứng dụng. Để tìm ra nguyên nhân của cái bug này, ta có thể xem các commit gần đây được đưa lên. Rõ ràng trước đây cái bug chưa hề tồn tại, mà giờ lại có, chứng tỏ có vấn đề trong các commit gần đây. Và đây là lúc các commit message chuyên nghiệp có thể cứu vớt đời bạn, tiết kiệm cho bạn cả tấn thời gian. Bạn có thể lọc ra: ừm commit này chỉ là change text, không liên quan; commit này fix bug ABC ở trang DEF, nên không liên quan; aha, commit này thêm một tính năng mới, có đánh dấu là BREAKING CHANGE, có khả năng rất cao nó gây ra bug,...
Một tình huống khác...
Bạn là một thành viên mới của team và bắt đầu làm việc với dự án. Bạn chưa từng đụng tay vào dự án này trước đây, thật gian nan. Nếu như bạn được giao một task là thêm một số logic vào một đoạn nào đó trong code, nếu như các anh em thiện lành đi trước có thể để lại cho bạn các commit message chất lượng (và clean code nữa thì toẹt vời) thì các commit message này có thể giúp bạn rất nhiều trong việc tìm ra cần thêm code vào đâu và thêm như thế nào.
Với anh em dev, fix một cái bug hay thêm một tính năng vào một hoặc hai tháng trước là gì đó xa xôi trôi vào thời tiền sử, chả ai nhớ nổi. Đừng nói là người khác, mà đến cả chính bạn có khi cũng chả nhớ nổi mình đã làm cái qq gì vào lúc đó. Chính các commit message chuyên nghiệp mới là nguồn resource quý giá cho cả bạn và đồng nghiệp lúc này.
Vậy một commit message chuyên nghiệp là gì?
Thật ra có rất nhiều cách để viết ra được một commit message chất lượng. Vấn đề cốt lõi ở đây là:
Chọn một style phù hợp nhất với team và dự án, sau đó luôn tuân thủ style đã chọn.
Một commit message chuyên nghiệp cần đạt các tiêu chuẩn sau:
- Nó dễ hiểu kể cả khi chỉ cần nhìn vào header của message (chúng ta sẽ nói về cái header này sau)
- Nó vừa đủ, không cần quá chi tiết
- Nó rõ ràng
OK. Giờ chúng ta sẽ đào sâu hơn vào vấn đề.
Chào mừng đến với Atomic Commits (commit nhỏ xinh)
Điều quan trọng cần được nhắc lại.
Chọn một style phù hợp nhất với team và dự án, sau đó luôn tuân thủ style đã chọn.
Mặc dù việc chọn một style phù hợp với team là quan trọng, nhưng việc mọi người kỷ luật tuân thủ style ấy mới là điều cốt lõi. Các commit cần phải nhỏ vừa phải.
Nếu một commit chứa nhiều thay đổi đến nỗi khiến cho bạn không biết phải viết commit message như thế nào, thì cái cần xem lại không phải là commit message mà là bản thân commit đó. Hãy chia nhỏ nó ra thành nhiều commit.
Giả sử nếu như chúng ta commit 2 thay đổi chung với nhau, ví dụ: fix 1 cái bug và "tiện tay" refactoring lại code để nhìn cho clean hơn, thì chuyện gì xảy ra?
Thứ nhất, sẽ cần một commit message rất dài để diễn tả đầy đủ: Cái commit này làm cái qq gì?
Thứ hai, giả sử cái code để fix cái bug lại gây ra những cái bug khác. Trong trường hợp đó, chúng ta cần revert code về thời điểm trước commit chẳng hạn, thì điều này đồng thời gây ra mất các đoạn code refactoring luôn (tui chẳng liên quan đến các cái bug này, mắc gì cho tui bay màu luôn). Anh dev code cái commit đó cũng cay cú vì tốn bao nhiêu công refector code cho clean.
Thứ ba, nếu một ai đó sau này truy vết các commit trong lịch sử git để coi lại cách fix cái bug chẳng hạn, thì người này cũng điên đầu để phân biệt đâu là code fix bug, đâu là code refactor. Thật là mệt mỏi và tốn cost không cần thiết.
Vậy nên, hãy giữ các commit nhỏ xinh. Bằng cách nào?
Hãy bắt đầu từ lúc nhận task. Hãy break task lớn này ra thành các việc nhỏ hơn.
Ví dụ: Thêm chức năng cho phép xóa hàng loạt items.
Chúng ta có thể break down nó thành các phần việc nhỏ hơn như:
- Thêm UI cho phép chọn nhiều item để xóa ở front-end của Desktop
- Cập nhật UI để phù hợp cho việc chọn nhiều item để xóa ở front-end của Smartphone
- Cập nhật backend API controller để có thể xóa nhiều item dựa vào ID
- Cập nhật backend API logic để có thể xóa nhiều item dựa vào ID
Với mỗi một phần việc nhỏ này, hãy biến nó thành một commit. Như vậy các commit của bạn sẽ nhỏ xinh và commit message sẽ dễ dàng mô tả chính xác commit này làm gì mà không cần dài dòng.
Commit message cần Ngắn gọn và rõ ràng
Commit message cần phải mô tả được commit của chúng ta đã làm gì với các behavior của code base hiện tại, không phải là chúng ta đã thay đổi gì trong code base hiện tại. Chúng ta có thể dễ dàng xem chi tiết những dòng code nào đã được xóa đi, thêm vào, chỉnh sửa bằng git diff
, do đó không cần lặp lại điều này trong commit message.
Ví dụ: Tui đã thêm dòng abc vào file xyz ở dòng 123.
Điều này không cần thiết.
Điều cần thiết và quan trọng mà commit message cần trả lời được đó là: "Điều gì sẽ xảy ra nếu như những thay đổi ở commit này được applied". Nếu như câu trả lời cho câu hỏi trên không thể ngắn gọn và rõ ràng, có thể bởi vì commit của bạn không atomic (nhỏ xinh), và đã có quá nhiều thay đổi trong một commit.
Commit message cần được viết ở Thì hiện tại đơn
Chắc không cần bàn cãi, chúng ta, những con dev chân chính và yêu nghề, nên viết commit message bằng tiếng Anh, đúng ngữ pháp, chính tả, và ở thì Hiện tại đơn.
Right: add feature to alert admin for new user registration
Wrong: Added feature ... (past tense)
Tại sao cách viết bên trên là đúng?
Mình nhắc lại câu này xíu, vì điều gì quan trọng xứng đáng được nhắc lại.
Điều cần thiết và quan trọng mà commit message cần trả lời được đó là: "Điều gì sẽ xảy ra nếu như những thay đổi ở commit này được applied". (What happens if the changes are applied?)
Cách viết bên trên đúng vì nó trả lời được câu này một cách xuôi tai.
Q: What happens if the changes are applied?
A: "If applied, this commit will add a feature to alert admin for new user registration"
Commit message cần Đủ chi tiết
Một commit quá chi tiết cũng không tốt. Nếu ai đó cần độ chi tiết đến mức đó, họ sẽ đọc code, vì code là document chi tiết nhất. Ví dụ: không cần liệt kê các file đã thay đổi. Git có thể giúp chúng ta làm điều đó.
Do đó, thay vì trả lời cho câu hỏi: "Những gì đã thay đổi?", hãy trả lời câu hỏi sau: "Những thay đổi này để làm gì?"
Format của một commit message chuyên nghiệp
Hãy bắt đầu bằng Git conventions.
Git gợi ý rằng, một commit message nên có 3 phần: chủ đề (subject), mô tả (description) và ticket number.
Hãy xem một mẫu commit message được đề cập ở trang chủ của Git (Git's website)
Subject line (try to keep under 50 characters)
Multi-line description of commit,
feel free to be detailed. (Up to 72)
[Ticket: X]
Chủ đề tốt nhất nên ngắn hơn 50 kí tự để khi ai đó sử dụng lệnh git log --oneline
, họ sẽ có được một output đẹp. Mô tả tốt nhất nên chứa tối đa 72 kí tự trên một dòng.
Tại sao lại là 50 và 72? Preslav Rachev có một bài viết mô tả lí do đằng sau quy tắc 50/72 này. Có thể tóm tắt lí do như sau: Tại sao lại là tối đa 50 kí tự cho phần Chủ đề (Subject)? Bởi vì phân tích độ dài trung bình của các commit ở đóng góp cho Linux kernel đưa ra con số này. Tại sao lại là tối đa 72 kí tự trên một dòng cho phần Mô tả (Description)? Bởi vì khi sử dụng lệnh git log
trên terminal, git sẽ output log ra ở định dạng 80 cột trên một hàng, thêm vào đó, git
lại thêm 4 space vào bên trái của mỗi dòng Description. Do đó, chúng ta sẽ chừa thêm 4 space ở bên phải để canh giữa output này. Kết quả là 80 - 4 space bên trái - 4 space bên phải = 72 kí tự một dòng.