- Conventional Commits cố gắng gán ý nghĩa cho thông điệp commit theo dạng
<type>[optional scope]: <description>, nhưng lại đặt loại thay đổi lên trước và coi phạm vi là tùy chọn, khiến thông tin cần thiết cho việc tra cứu thực tế bị đẩy xuống sau
- Người đóng góp, người debug và người ứng phó sự cố đều tìm trong log commit khu vực mã mà thay đổi đã chạm tới; bug có thể phát sinh từ bất kỳ loại thay đổi nào, nên scope quan trọng hơn type
- Với
fix(compiler): prevent namespaced SVG <style> elements from being stripped, chỉ riêng phần mô tả cũng đã cho thấy đây là sửa lỗi; còn refactor(core): Update webmcp support to use document.modelContext cho thấy một commit có thể đồng thời là sửa đổi, refactor và thêm tính năng, nên type vừa trùng lặp vừa hạn chế
- Việc tự động tạo CHANGELOG và quyết định tăng semantic version gặp vấn đề vì độc giả của log commit và changelog là khác nhau; thêm vào đó, revert, việc vô tình phá vỡ tương thích ngược và việc xử lý lỗi phá vỡ về sau có thể khiến kết quả lệch đi
- Thông điệp commit theo kiểu tiền tố scope cho thấy chủ thể thay đổi trước tiên, và điều kiện build hoặc deploy cũng nên dựa trên các tệp thay đổi trong
git diff thay vì loại ở tiêu đề
Ưu tiên sai thứ tự
- Conventional Commits đặt mục tiêu gán ý nghĩa cho thông điệp commit để giúp lập trình viên và người dùng cuối hiểu được thay đổi
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
- Dòng tiêu đề gồm
<type> như fix, feat, chore, docs, refactor, một scope tùy chọn và phần mô tả
- Khuyết điểm cốt lõi là cấu trúc này ưu tiên loại thay đổi là type hơn scope, tức chủ thể thực sự của thay đổi
- Việc scope là tùy chọn khiến thông tin quan trọng nhất của commit có thể bị thiếu, còn việc đặt type ở đầu tiêu đề làm đảo ngược thứ tự ưu tiên
Vì sao scope quan trọng hơn type
- Người đóng góp đọc log commit để tìm các thay đổi kể từ lần đóng góp gần nhất, nắm dòng chảy tổng thể của dự án, hoặc tìm những commit có thể xung đột với phần việc đang làm khi pull hay rebase
- Người debug tìm những thay đổi đã chạm tới khu vực liên quan đến thành phần nơi bug xuất hiện; vì bug có thể phát sinh từ bất kỳ type thay đổi nào, nên thông tin type không giúp ích nhiều
- Người ứng phó sự cố sẽ rà log commit quanh thời điểm xảy ra sự cố để tìm khu vực gây ra vấn đề; nếu tại điểm số lỗi API inbound tăng vọt có một commit thuộc scope
auth, đó sẽ là một ứng viên nguyên nhân rất đáng nghi
- Với người đọc log commit, thông tin quan trọng không phải thay đổi thuộc loại gì mà là nó đã chạm tới khu vực nào
Tính trùng lặp và giới hạn của type
Giới hạn của lời hứa tự động hóa
- Ý tưởng tự động sinh CHANGELOG từ commit bằng các công cụ như git-cliff hay conventional-changelog có vấn đề ở chỗ độc giả của log commit và changelog là hai nhóm khác nhau
- CHANGELOG hướng tới người dùng, tập trung vào việc hiểu khác biệt về mặt chức năng và kinh doanh giữa các phiên bản
- Log commit hướng tới lập trình viên, tập trung vào việc đọc hiểu codebase đã thay đổi theo thời gian ra sao và dòng chảy thay đổi theo góc nhìn scope
- Trong các dự án có độ phức tạp từ trung bình trở lên, một tính năng có ý nghĩa thường được đưa vào qua nhiều commit; với lập trình viên, quá trình triển khai là hữu ích, nhưng với người dùng cuối thì chỉ tính năng hoàn chỉnh mới quan trọng
- Commit revert quan trọng với lập trình viên vì nó là một phần của dòng chảy trong log commit, nhưng với người dùng cuối thì một thay đổi đã bị hoàn tác cũng giống như chưa từng được tạo ra
- Việc tăng semantic version dựa trên type của commit có thể dẫn tới các vấn đề như tăng major dù thay đổi phá vỡ tương thích ngược đã bị revert, tăng minor hoặc patch sai vì chỉ về sau mới phát hiện ra sự phá vỡ, hoặc đánh dấu là breaking change dù nó đã được trung hòa khi gộp với các commit tiếp theo
- Trong những tình huống đó có thể sửa lịch sử bằng rebase, nhưng workflow có thể ngăn cản hoặc làm hỏng việc này, đồng thời làm giảm độ tin cậy của dòng chảy mà log commit truyền tải
- Nếu dùng type trong tiêu đề commit để kích hoạt quy trình build hoặc deploy, thì một commit mang tiêu đề
docs: fix typos vẫn có thể lén đưa lỗ hổng vào hệ thống xác thực và qua mặt công cụ tự động
- Điều kiện build và deploy nên được quyết định bằng cách xác định các tệp đã thay đổi qua
git diff hơn là dựa vào tiêu đề commit
Vấn đề áp dụng và phương án thay thế
- Conventional Commits cho phép dự án tự định nghĩa tập type riêng, nhưng nhiều dự án chỉ lấy nguyên bộ type mặc định của commitlint, điều này có thể không phù hợp với đặc thù từng dự án
- Đặc tả Conventional Commits về mặt kỹ thuật chỉ định nghĩa
fix và feat, còn các type bổ sung được giao cho từng dự án tự quyết
- Trong môi trường doanh nghiệp, yêu cầu quản lý thay đổi và kiểm toán đôi khi buộc mọi thông điệp commit phải có mã ticket; nếu
<scope> bị dùng làm chỗ cho mã ticket thì metadata hữu ích sẽ biến mất
- Linux, FreeBSD, Git, Go, NixOS và Node.js đều dùng thông điệp commit với tiền tố scope phù hợp với dự án
- Trong Linux kernel, scope tự nhiên là subsystem; trong dự án Go là package path; còn trong kiến trúc microservice thì đó là tên microservice
- scopedcommits.com cổ vũ việc quay lại định dạng thông điệp commit lấy scope làm trung tâm và tách riêng việc tạo CHANGELOG khỏi quản lý log commit
- Những lợi thế được cho là của Conventional Commits đã không chuyển hóa thành lợi ích thực tế, còn sự phổ biến trong các dự án mã nguồn mở và xu hướng AI chọn mặc định kiểu này lại khiến thông điệp commit pha trộn anti-pattern lan rộng
2 bình luận
Ý kiến trên Hacker News
Các lập trình viên dường như lúc nào cũng thích tranh cãi và than phiền về việc thiết lập tối ưu là gì, kể cả với những thứ nhỏ nhặt như tab và space
Điều đó không có nghĩa Conventional Commits là lựa chọn tốt nhất như một kiểu mặc khải thần thánh để cấu trúc thông điệp commit, nhưng tôi cho rằng việc có một cấu trúc đã được quy ước và thống nhất kỳ vọng về thông điệp commit hiệu quả và quan trọng hơn nhiều
Tác giả nhấn mạnh khá nhiều rằng phạm vi quan trọng hơn loại, nhưng tôi không nghĩ sự khác biệt giữa
fix(compiler)vàcompiler fixlà vấn đề đáng phải sống chết vì nóTrong ngành công nghệ có rất nhiều thứ đã trở thành tiêu chuẩn dù không tối ưu, ví dụ như nếu làm lại JSON từ đầu thì nhiều người hẳn sẽ cho rằng nó nên hỗ trợ comment, định dạng số rõ ràng hơn, v.v.
Dù vậy, nó vẫn trở thành tiêu chuẩn vì trong nhiều bối cảnh nó tốt hơn những gì có trước đó; có thể tồn tại một định dạng tốt hơn hơi khác với Conventional Commits, nhưng có lẽ nó chưa đủ tốt đến mức đáng tạo ra thêm một kiểu cạnh tranh khác cho cấu trúc thông điệp commit
Thông điệp commit vẫn có thể rất tốt dù cấu trúc lỏng lẻo, miễn là truyền đạt rõ bản chất của thay đổi; ngược lại, nó cũng có thể rất rối hoặc không có thông tin gì dù cực kỳ có cấu trúc
Nhìn chung tôi đồng ý với tác giả: Conventional Commits không giải quyết được vấn đề cốt lõi là các thông điệp commit tệ
XML đủ tốt và là tiêu chuẩn, SOAP cũng đủ tốt và là tiêu chuẩn
Lập luận ở đây là Conventional Commits đủ tốt và đủ tiêu chuẩn hóa nên không đáng xem xét cấu trúc khác, nhưng cái “đáng” đó lại mang tính chủ quan
Nếu bạn commit và đọc PR mỗi ngày, thì cả những ma sát nhỏ do định dạng Conventional Commits tạo ra cũng có thể tích lũy; và nếu không coi nó như quy luật tự nhiên mà chừa ra các lựa chọn khác, điều đó sẽ hữu ích cho những nhóm thích cách khác
Đằng nào thì đa số các nhóm cũng chẳng tạo changelog
Đúng là phạm vi quan trọng, nhưng tôi nghĩ có thể suy ra nó từ nội dung commit
Khi rà soát diff, việc nhìn vào các đường dẫn bị chạm tới là một sanity check quan trọng, và một diff “test” thì không nên sửa mã xác thực production
Tuy vậy, nếu muốn thấy nó trong
--onelinethì tôi vẫn cho rằngfeat(auth):tốt hơnfeat:Tôi không đồng ý với lập luận rằng độc giả mục tiêu đã sai
Một commit
featthực sự nên mô tả thay đổi từ góc nhìn sản phẩm, và nên được sắp xếp sao cho các thay đổi refactor vô nghĩa được gom gọn trước, rồi mới chồng thay đổi tính năng nhỏ mới lên trênĐó cũng là điều hữu ích nhất để đưa vào phần mô tả diff, còn bối cảnh kỹ thuật như “vì sao chọn thuật toán X” thì nên được ghi vào comment hoặc
DECISIONS.mdđể khỏi bị thất lạcỞ các công ty chạy rất nhanh, chỉ những người hơi ám ảnh mới chăm chút mấy việc tẻ nhạt này trong lịch sử commit, nhưng trong các dự án mã nguồn mở thì việc giấu bối cảnh vào thông điệp commit lại quan trọng hơn nhiều
Có lý do để tồn tại những định dạng như Markdown và văn bản thuần, chứ không chỉ có JSON
Tôi đã review quá nhiều commit có tiêu đề là
small fixnhưng thực tế hoàn toàn không phải một sửa đổi nhỏKết luận thực sự là mỗi dự án có yêu cầu khác nhau
Trong hơn 30 năm dùng quản lý mã nguồn, tôi chưa từng có lần nào thấy việc đưa component vào phần mô tả theo một cách chuẩn hóa (trong bài gọi là scope) là hữu ích
Chỉ cần nhìn vị trí các tệp bị ảnh hưởng trong cây mã nguồn là đã rõ component nào thay đổi, và
bug,fix,featurecũng không bổ sung giá trị hữu ích nàoNếu không quan trọng thì đã chẳng được check-in
Thứ duy nhất tôi thấy hữu ích là liên kết hoặc ID của yêu cầu thay đổi liên quan, thứ mà bài viết hoàn toàn không đề cập
Commit vốn đã chứa thông tin về việc cái gì đã thay đổi, thứ còn thiếu là ngữ cảnh về lý do vì sao nó thay đổi
Ngay cả trong dự án cá nhân, tôi cũng đặt tham chiếu JIRA trong ngoặc vuông ở đầu phần mô tả, và dù chỉ là thứ tình cờ quyết định sửa trong lúc phát triển, tôi vẫn tạo một JIRA ngắn một dòng để lấy ID và ghi lý do vào đó
Việc nắm bắt “vì sao” là toàn bộ mục đích của thông điệp đó, và chỉ gắn một liên kết đến tài nguyên bên ngoài có thể biến mất vào lúc nào đó không phải là phương án thay thế tốt
Nếu là GitHub issue thì từ commit có thể lần ngược về thảo luận PR, và trong PR đó phải có issue được liên kết cùng các con trỏ khác
Tất nhiên, khi chuyển sang GitHub issue thì chúng tôi gần như bỏ hẳn JIRA, và vài năm sau instance đó bị tắt rồi xóa luôn
Giờ thì tất cả các thẻ JIRA đó đều vô dụng
Vì vậy, tôi lại thấy cần sự gắn kết chặt giữa issue tracker và kho git
Thứ thực sự mong muốn là tính di động, nhưng tôi không biết làm sao có được nó nếu không có sự gắn kết chặt
Lý tưởng nhất là nên có một định dạng chuẩn mở, nhưng trong thực tế GitHub là con gorilla khổng lồ định nghĩa định dạng đó, và nếu GitLab cùng các bản sao khác có thể nhập metadata dự án GitHub hoặc ít nhất là PR thì trên thực tế cũng gần như đạt tới điều đó
Dù sao thì một chính sách để lại các con trỏ cố định, bất biến tới một sản phẩm Atlassian mà có thể 5 năm nữa bạn không còn dùng nữa cũng không hay
Tôi thà chấp nhận chính sách rằng commit git phải tự đứng vững hoàn toàn và phải hòa toàn bộ thông tin về “vì sao” của thay đổi vào thông điệp commit hoặc chú thích trong mã nguồn
Nhưng tôi cũng nghĩ cách đó sẽ thất bại, vì mọi người viết quá ngắn trong commit git và làm mất thông tin khi tóm tắt issue, trong khi các trao đổi qua lại trong thảo luận PR lại hữu ích vì chứa nhiều hơn một bản tóm tắt lý do thay đổi bằng giọng của một người
Gom các tính năng mới trước rồi đến các bản sửa lỗi sẽ khiến người dùng không chuyên kỹ thuật dễ đọc hơn một chút
Thông điệp commit không phải để tạo changelog mà là dành cho các lập trình viên trong tương lai
Thời điểm chính mà lập trình viên đó đọc thông điệp commit là khi họ không hiểu vì sao commit ấy tồn tại
Đó là lúc họ không thắc mắc đã thay đổi cái gì, mà thắc mắc mục đích của một dòng cụ thể là gì
Vì thế họ chạy
blameđể xem commit, tác giả ban đầu có thể đã rời công ty, JIRA cũ có thể cũng biến mất, và manh mối duy nhất là thông điệp commithttps://dev.to/splix/the-why-behind-the-code-2bb1
Chẳng phải cứ đưa ngữ cảnh vào phần thân commit là được sao?
Tôi luôn thấy từ
choremà nhiều người dùng với Conventional Commits khá khó chịuCá nhân tôi từ lâu đã thích kiểu tiêu đề commit phong cách linux kernel như cũng may được nhắc tới ở đây
[0] https://www.kernel.org/doc/html/v7.0/process/submitting-patc...
Thái độ mà
chorehàm ý tạo cho tôi cảm giác rất phản cảmNó khiến tôi có cảm giác như tất cả phần còn lại đều phải được gắn nhãn
funhoặcindifferent, và những đánh giá cảm tính như vậy không có chỗ trong thông điệp commitupkeepCùng nghĩa nhưng không có sắc thái khinh miệt
Hơn nữa, nó còn giả vờ như ta biết trước tác động tổng thể của commit, trong khi thực ra là không
Khi có Conventional Commits, cả đồng đội lẫn LLM đều phải tốn thời gian và token để nghĩ ra cái cách đặt tên ngớ ngẩn đó
Phàn nàn chính của tôi về Conventional Commits là tiêu đề commit không chứa số issue
Trong tài liệu chuẩn nó thậm chí còn không được nhắc tới như một tùy chọn
Với tôi, đó gần như là thông tin quan trọng nhất trong thông điệp commit
Tôi không biết trong 15 năm qua đã có bao nhiêu lần mình phải đối chiếu phần mô tả issue mà các commit cũ tham chiếu tới để nắm được toàn bộ ngữ cảnh của thay đổi
Tôi cứ nghĩ thói quen này là một dạng chuẩn, cho đến khi biết về Conventional Commits mới nhận ra không phải vậy
Tôi hoàn toàn không hiểu vì sao nó lại phổ biến
Cá nhân tôi thích đưa issue vào dạng git trailer hơn
fix thing in fooIssue: ABC-123Git có khá nhiều tính năng tích hợp sẵn để phân tích và định dạng các trailer như thế này, nên có thể dễ dàng tạo alias
git logtùy chỉnh để xem trực tiếp hoặc parse trong CINếu đã đang lướt qua changelog vốn đã bị giới hạn số ký tự, thì việc có
XYZ-999999trong thông điệp commit chính thật ra không quá đáng quan tâmGắn thẻ bằng trailer thì tốt, nhưng tôi muốn thấy commit đã làm gì hơn nhiều so với số issue Jira
Tôi chỉ xem đó là vấn đề khi có yêu cầu phải đặt issue key ở ngay đầu tiêu đề
Ngay cả vậy tôi cũng nghĩ điều đó làm giảm tính dễ đọc
Tôi không hiểu vì sao không thể đơn giản gắn nó đâu đó sau cái định dạng lỉnh kỉnh của Conventional Commits
Issue key vốn phải có thể được trích xuất bằng regex kiểu số đứng sau tiền tố chữ-số, nên các “tiêu chuẩn” kiểu này hầu như không cần phải dành riêng một chỗ cho nó
Cá nhân tôi thì không dùng Conventional Commits, và nếu commit có liên quan đến issue đó thì chỉ cần thêm vào cuối trong ngoặc đơn
Nếu quan hệ chặt hơn, như kiểu commit đó sửa issue, thì tôi cũng thêm trailer
Fixesvào thông điệpHay đấy
Từ trước đến nay chúng tôi vẫn viết kiểu
fix(ABC-123): some message here, việc liên kết hoạt động tốt và khi render vào ghi chú phát hành tự động cũng trông rất ổnĐó không phải là tiêu chuẩn mà là thông lệ
Chỉ cần thống nhất trong nhóm một tiêu chuẩn đưa ticket ID vào thông điệp commit là được
Nếu muốn để máy đọc được thì hãy dùng footer/trailer
Tôi chẳng có gì tốt đẹp để nói về Conventional Commits
Định dạng đó chiếm chỗ ở phần được đọc nhiều nhất của thông điệp, còn category hay type thì rất ít thông tin
Chỉ cần viết động từ tiếng Anh rõ ràng trong tiêu đề như một câu là thay thế được, và một câu bình thường dễ đọc hơn nhiều so với ba loại dấu câu như
:,(),!Cùng lắm thì tôi chịu được “phạm vi” trong tiêu đề, mà cái đó cũng đã có từ trước cả thông lệ này
Ở chỗ làm tôi xây web app cho người dùng không chuyên kỹ thuật, và changelog cho những người dùng đó có thể được viết ổn bằng tiếng Na Uy
Thông điệp commit không liên quan gì đến người dùng, và việc yêu cầu mọi commit đều phải đủ tốt để đưa vào changelog cho người dùng cuối là điều với chúng tôi sẽ chưa xảy ra trong tương lai gần
Thay vào đó chỉ cần dùng footer/trailer
Nơi Conventional Commits thực sự hữu ích là triển khai liên tục
Mỗi khi được merge vào
main, có thể tự động gắn thẻ SemVer và triển khai, vì các quyết định cần cho việc gắn thẻ và quản lý phiên bản đã được lập trình viên đưa ra ngay lúc viết thông điệp commitTôi hoàn toàn thừa nhận rằng nó không phù hợp với những dự án khổng lồ như Linux kernel
Nhưng với 99% dự án, kết hợp Conventional Commits với SemVer sẽ cải thiện lớn so với quy trình phát hành hiện tại và dễ tự động hóa hơn nhiều
git tagsgit describethường đã đủ cho quản lý phiên bản trong triển khai liên tục, vàv1.2.3-4-gabcdefmô tả commit đủ chính xác theo tiêu chuẩn của git, đồng thời cũng giống SemVer đủ để đặt ra kỳ vọngĐiều này đặc biệt đúng khi chỉ thêm
git tagsmới dựa trên đánh giá của con người, ví dụ như thay đổi này là thay đổi phá vỡ nên giờ cần gắn một major mớiVới số phiên bản theo định dạng
git describe, tranh luận thực chất chỉ là có nên đổi dấu gạch ngang đầu tiên thành dấu cộng để khớp kỳ vọng SemVer hơn hay không; và nếu việc ép theo kỳ vọng SemVer, như sắp xếp phiên bản đúng trong trình quản lý gói, là có giá trị, thì có thể chuyển bằng một regex đơn giảngit describegiúp tự động hóa CD dễ dàng, nhưng vẫn để quyết định số phiên bản cho con người thông qua việc chọngit taghoặc GitHub Releases, thay vì đoán dựa trên các từ khóa ma thuật trong lịch sử commitỞ công ty, chúng tôi cũng ép buộc cả “tag” tùy theo đối tượng nào quan tâm đến thay đổi
Ở đây tag không phải git tag mà là chuỗi trong tiêu đề PR, và dựa trên “tag” đó chúng tôi tạo changelog cho từng nhóm
Nếu muốn đánh số phiên bản theo cách kỳ quặc đó thì chỉ cần thêm một cụm từ ma thuật vào phần thân commit là được
Như vậy cũng không bị giới hạn trong một từ duy nhất
Tôi khá ghét kiểu tiêu đề này
Những cách viết như “Stop something” có vẻ rất thịnh hành, nhưng nó mang giọng điệu ra lệnh và tạo cảm giác “tôi chắc chắn đúng”
Tôi không hiểu sao không viết kiểu như “In favour of something” hay “A case against something”
Bạn không cần đồng ý với quan điểm đó, nhưng đòi hỏi phải làm mờ cách diễn đạt là một phản ứng yếu
considered harmful, nhưng vẫn hơi độc hạiCốt lõi có vẻ là cố làm cho một sở thích cá nhân khá tùy ý, ví dụ như muốn đổi thứ tự A và B, trông to tát hơn thực tế
Với nhiều người điều đó là thô lỗ, nhưng nền kinh tế chú ý lại thưởng cho cách làm đó
Sửa: có vẻ họ đã đổi tiêu đề thành ít khiêu khích hơn
Làm tốt lắm
Tôi không thích Conventional Commits lắm, nhưng cứ để mọi người dùng thứ họ muốn
Có một meme đã ảnh hưởng đến một phần của thể loại tiêu đề này
Kỳ lạ
Lý do chính để dùng kiểu thông điệp commit này là tự động hóa CI/CD
Sửa: lúc đọc lần đầu tôi đã bỏ sót phần này trong bài, nhưng thực ra bài có đề cập
Xin lỗi
Kiểu commit đứng ở đầu vì nó cho workflow tự động biết phải xử lý commit như thế nào
Ví dụ nếu làm CD, khi chỉ có nhiều commit
fix:thì chỉ tăng số bản vá trong phiên bản ngữ nghĩaNếu commit
feat:thì tăng phiên bản minor, cònfeat!thì tăng phiên bản majorNgay cả khi không dùng CD cho phát hành, thông điệp commit ngữ nghĩa cũng thường được dùng để tự động tạo changelog
Dĩ nhiên thường không nên đưa nguyên thông điệp commit Git vào changelog
Những thông điệp đó hướng đến nhà phát triển chứ không phải người dùng
quản lý phiên bản ngữ nghĩa sẽ hỏng khi revert, và changelog tự động thì sai đối tượng độc giả
Dạo này tôi dùng CalVer thay cho SemVer nên không còn là vấn đề nữa, nhưng ý tưởng tự động tăng phiên bản một cách thông minh vẫn rất hấp dẫn
Có
fixhayfeattrong tiêu đề commit cũng không cung cấp thông tin hữu ích cho người đang rà logÝ là phải bỏ Conventional Commits để AI có thể tạo commit dễ hơn đấy mà
Nếu đảo ngược thứ tự thì sự khó chịu lớn nhất của tôi thật ra được giải quyết
Rốt cuộc tính năng là gì?
refactor(core): Update webmcp support to use document.modelContextNhư tác giả nói, ranh giới giữa sửa lỗi, cải tiến và dọn dẹp chung rất mơ hồ, còn việc tách từng thay đổi mang tính ngữ nghĩa thành các commit riêng rốt cuộc chỉ tạo thêm việc vô ích cho mọi người vì đằng nào sau này cũng có thể bị squash lại
Tôi xem Conventional Commits là sản phẩm phụ sinh ra từ nỗ lực tự động hóa SemVer, chứ không phải thứ trực tiếp giải quyết một vấn đề nào khác
Tôi nghĩ changelog vốn dĩ không nên được tự động hóa
Nếu cần danh sách thì cứ xem
git loglà đượcChangelog là cơ hội để truyền đạt cho một nhóm độc giả rộng hơn biết bên trong thực sự đã xảy ra chuyện gì
“Độc giả của changelog hoàn toàn khác với độc giả của commit log”
“Changelog là dành cho người dùng”
Có vẻ con thuyền đó đã rời bến rồi
Hầu hết các công ty hài lòng với kiểu “Bug Fixes & Performance Improvements”
Ít nhất nếu đã không định bỏ công sức ra thì changelog được tạo tự động vẫn còn tốt hơn là không có gì
uv:vào các commit hiển thị cho người dùngSau đó mỗi tuần tôi tìm chúng, dùng nguyên văn hoặc chỉnh nhẹ câu chữ
Tôi cũng đưa chúng vào menu Help/Release-notes của chính sản phẩm
Bảo tôi ngừng làm một việc mà tôi vừa làm vừa chưa từng nghe nói tới thì cũng hơi buồn cười
Thường thì người ta chỉ gắn tiền tố đặc biệt cho những thứ như migration schema cơ sở dữ liệu hoặc các thay đổi quan trọng khác
Có vẻ anh ta cũng đặt tên commit không giỏi, và chắc cả tên symbol cũng không giỏi nốt
Chỉ là vấn đề năng lực thôi, đang công khai than thở nên cứ bỏ qua là được
Ý kiến trên Lobste.rs
Thật mừng vì đây là một bài viết sắp xếp các lập luận phản bác conventional commits bằng lý lẽ thay vì chỉ là cảm giác bài xích theo bản năng
Tôi chưa từng nghĩ sâu về việc vì sao mình ghét nó, và cũng tự hỏi có phải vì tôi đã bắt đầu liên hệ nó với mã do LLM tạo ra hay không. Đặc biệt tôi ghét nhất
chore:; mong là chúng ta đừng tái phát minh ký pháp Hungarian. Ngay từ đầu nó đã không nên tồn tạichore:thậm chí không còn trong Angular commit style guide nữa, có lẽ vì họ nhận ra nó quá mơ hồ nên đã gộp vàobuild:Ngay cả khi còn trong style của Angular, mô tả cho
chore:cũng nêu ra các mục đích sử dụng khá cụ thể, nhưng ở một số dự án mã nguồn mở thì có vẻ người ta gắn nó theo cảm tính cho những việc theo đúng nghĩa là thấy ngại làmTôi không thích conventional commits, nhưng phương án thay thế được đề xuất có vẻ bỏ qua lý do scope là tùy chọn
Trong các dự án nhỏ không có nhiều module tách bạch, khái niệm “scope” không hữu ích lắm. Một thực hành hữu ích mà cả hai bên đều bỏ sót là thêm số issue hoặc số ticket vào tiêu đề commit, vì như vậy sẽ dễ nắm được ngữ cảnh bổ sung của thay đổi và đặc biệt hữu ích khi review code. Tuy vậy, tôi không thích việc biến số ticket thành bắt buộc, vì như thế sẽ sinh ra hàng loạt ticket vô dụng cho các thay đổi nhỏ nhặt; nhưng nếu một thay đổi xử lý một bug hay một task cụ thể thì nó nên được liên kết với bug hoặc task đó
Dù sao nó vẫn tốt hơn “type” commit bị lặp ý, thứ mà lẽ ra chỉ cần nhìn dòng tiêu đề là đã thấy rồi
Nếu thay đổi khớp rõ ràng với một ticket thì dùng commit kiểu “số ticket”, còn không thì dùng cách khác. Có thay đổi hợp với type hơn nhưng ít hợp với scope hơn, và ngược lại, nên cũng có thể trộn scoped commits với conventional commits
Tôi chỉ muốn nói là “đừng dùng phông chữ đơn cách cho văn bản dạng đoạn”
Dù vậy, nhìn chung tôi vẫn đồng ý với tiền đề của bài viết
Ngay cả khi commit message không hay, nếu muốn hình dung phạm vi thay đổi thì tôi khuyên nên dùng
git log --name-onlyhoặcgit log --statthường xuyênNhìn tên file cũng giúp khá nhiều để biết mỗi commit đã thay đổi gì mà không cần mở từng commit ra xem hết
Cách tôi thực sự thích là bắt buộc dùng kiểu conventional commit cho tiêu đề PR
Tiêu đề PR vẫn có thể được maintainer chỉnh sửa sau khi merge, không cần viết lại lịch sử commit, và nếu dùng cùng các công cụ như release-drafter thì có thể tự động hóa changelog có ý nghĩa trong GitHub Releases. Nó cung cấp mức độ chi tiết phù hợp với các bên liên quan mà tác giả nhắc đến, tức là tách riêng tính năng, bản sửa lỗi và thay đổi phá vỡ tương thích, đồng thời cũng tự động xử lý bản nháp GitHub Release tiếp theo với semver hợp lý
Nhận xét trong bài rằng một thành phần như
parse-libkhông nên là tùy chọn là đúng, và tôi cũng đồng ý rằng việc ép buộc conventional commits có thể làm người đóng góp mới nản lòng. Nhưng các phương án thay thế cũng không hẳn tốt hơnDù vậy, định danh thay đổi phá vỡ tương thích như
fix!(parse-lib): Don't leave sparse holes when parsing JSON arraysvẫn truyền tải khá nhiều thông tin. Đó là bản sửa lỗi cho một thành phần cụ thể, việc sửa lỗi đó kéo theo một thay đổi phá vỡ tương thích không thể tránh khỏi, và còn hàm ý một mức tăng semver kiểu minor nữa. Những thứ như vậy có thể dùng ở tiêu đề PRTôi thừa nhận mình đã quá sa đà vào conventional commits như một cách khuyến khích kỷ luật commit, và rồi nó thành thói quen
Giờ đây đôi khi tôi thấy nó mang tính hạn chế và tùy tiện. Ở vài dự án tôi thậm chí không rõ đó có phải là thông lệ thực sự hay không, và dần chuyển sang gần với phong cách Linux/Go/Node hơn; trong các monorepo có nhiều cấu hình khác nhau, việc viết
[service]: [what changed]có vẻ tự nhiên hơn là cố ép ra một type. Từ giờ tôi định thử nghiệm nhiều hơn với phong cách commit cá nhân dựa trên tiêu chí cái gì trông hữu ích, thay vì cố khớp vào một quy ước cứng nhắc, và scoped commits có vẻ là một điểm khởi đầu tốtchore(lobsters): add my 2 cents on conventionals commits [JIRA-69420]Tôi đồng ý với gần như mọi thứ, nhưng có một điểm tôi nhìn khác đi: đoạn nói rằng “nó cho người đóng góp thấy một hồ sơ mang tính xét lại, làm giảm độ tin cậy của câu chuyện mà commit log kể lại”. Có vẻ tác giả chủ yếu đang nói về các nhánh công khai, và nếu là nhánh công khai thì đó là lời khuyên hợp lý. Nhưng điều đó không nên áp dụng cho nhánh riêng tư. Chỉ cần làm sao để người review thay đổi cuối cùng — tức maintainer hoặc chính tôi của 10 năm sau — có thể hiểu được là đủ; không cần giữ lại một dòng suy nghĩ trước sau không khớp, hoặc tệ hơn là cả một chùm commit
address reviewCâu trả lời cho “vì sao scope là tùy chọn?” là trong các dự án nhỏ thì toàn bộ dự án chính là scope
Tôi đồng ý rằng “type” của commit không quá hữu ích, nhưng cũng không chắc giữa scoped commits và conventional commits có khác biệt lớn đến vậy không. Scoped thực chất chỉ là conventional bỏ đi “type”, còn các phân loại như fix, feat, refactor, chore thì vẫn là những phân loại chấp nhận được
Nếu mọi người đều chỉ bê nguyên mặc định của commitlint vào dùng, thì chẳng phải chỉ cần làm cho người ta dùng nó tốt hơn hay sao?