Git Notes: Tính năng hay nhất nhưng bị ghét nhất của Git (2022)
(tylercipriani.com)- Git notes là tính năng gắn metadata vào một namespace riêng mà không thay đổi đối tượng Git, nhưng không được dùng rộng rãi vì khả năng sử dụng kém và mức độ được áp dụng còn hạn chế
- Có thể bổ sung thông tin mới mà không cần sửa commit message cũ, nên rất phù hợp với các bản ghi do hệ thống tự động để lại như review, build, thông tin ticket
- Dự án Git và Gerrit thực sự tận dụng notes để có thể xem thảo luận trên mailing list theo từng commit, kết quả test và thông tin reviewer trong
git log - git-appraise của Google triển khai code review phân tán trên git notes, cho phép thực hiện yêu cầu review, bình luận, review và merge ngay trên máy local
- GitHub đã ngừng hiển thị commit notes vào năm 2014; còn blob và tree notes đòi hỏi phải quen với các lệnh nội bộ của Git, nên dù có tiềm năng phân tán lịch sử dự án, chúng vẫn khó dùng
Metadata không thay đổi đối tượng Git
- Git notes là tính năng lưu metadata riêng cho các đối tượng mà Git theo dõi
- Đối tượng không chỉ gồm commit mà còn bao gồm cả blob và tree
- Thông tin được gắn vào một namespace riêng mà không sửa chính đối tượng đó
- Commit message đã nằm trong history thường khó sửa một cách an toàn, nhưng dùng notes thì có thể thêm thông tin mới cả vào các commit cũ
- Có thể gắn ghi chú bằng
git notes add -mnhư saugit notes add -m 'Acked-by: <tyler@tylercipriani.com>' - Sau đó, trong
git log, ghi chú sẽ hiển thị dưới commit tương ứng dưới dạng khốiNotes:
- Có thể gắn ghi chú bằng
- Năm 2010, trên GitHub.blog, Scott Chacon xem notes là tính năng phù hợp hơn để gắn các bản ghi tự động như ticket, hệ thống build thay vì dùng cho đối thoại giữa các lập trình viên
Cách dùng thực tế và những điểm nghẽn
- Dự án Git dùng notes để liên kết từng commit với các cuộc thảo luận trên mailing list
Notes (amlog)của commit ví dụ có chứaMessage-Id, và giá trị này dẫn đến luồng thảo luận về patch
- notes cũng được dùng cho các mục đích như theo dõi thời gian làm việc theo commit hoặc branch, thêm thông tin review/test vào
git log, và code review hoàn toàn phân tán - Plugin reviewnotes của Gerrit cho phép xem metadata code review ngoại tuyến ngay trong Git
- Các lệnh để lấy và hiển thị notes như sau
git fetch origin refs/notes/review:refs/notes/review git log --show-notes=review - Thông tin hiển thị gồm
Verified+1,Verified+2,Code-Review+2,Submitted-by,Submitted-at,Reviewed-on,Project,Branch, v.v.
- Các lệnh để lấy và hiển thị notes như sau
- git-appraise của Google là hệ thống “fully distributed code review” được xây dựng trên git notes
- Hoạt động độc lập với các code forge như GitHub, GitLab
- Có thể thực hiện yêu cầu review thay đổi, bình luận về thay đổi, review và merge trên máy tính local
- Cũng bao gồm giao diện web
- Điểm yếu lớn nhất là khả năng sử dụng
- GitHub đã ngừng hiển thị commit notes vào năm 2014
- Với commit notes, có thể dùng thiết lập
gitconfigđể phần nào đơn giản hóa việc tự động fetch và hiển thị tronggit loggit config --add \ remote.origin.fetch \ '+refs/notes/*:refs/notes/*' git config \ notes.displayRef \ 'refs/notes/*' - Muốn lưu notes cho blob hoặc tree thì cần quen với plumbing của Git
- Git phân tán lịch sử code, nhưng nhiều giá trị của kho Git lại bị khóa trong các forge như GitHub
- git notes có thể trở thành một con đường để phân tán không chỉ code mà cả lịch sử toàn bộ dự án
1 bình luận
Ý kiến trên Hacker News
Một tính năng khác ít được biết đến là git trailers: https://alchemists.io/articles/git_trailers
Đây là dữ liệu có cấu trúc dạng khóa-giá trị có thể đưa vào khi tạo commit, và một số hệ thống dùng nó để đính kèm metadata. Ví dụ Gerrit dùng tính năng này để gắn Change-Id
Nó cho phép gắn văn bản vào nhiều đối tượng cơ sở dữ liệu trong PostgreSQL. Sẽ rất hay nếu PostgreSQL cũng có một tính năng metadata cho đối tượng cơ sở dữ liệu ở dạng khóa-giá trị có cấu trúc và có thể chỉnh sửa
[skip ci], có lẽ để các hệ thống con tiêu thụ commit message dễ loại bỏ hơn: https://docs.github.com/en/actions/managing-workflow-runs-an...Tôi không rõ vì sao họ bắt buộc nó phải là trailer cuối cùng, có thể là do regex
Việc này hữu ích khi làm việc với upstream mã nguồn mở và muốn trau chuốt branch thật hoàn hảo bằng
git rebase -i. Bây giờ có vẻ đưa thông tin đó vào git trailers sẽ tốt hơn. Về Change-Id, sẽ tốt nếu bản thân Git có những định danh kiểu này để các công cụ cũng có thể hiểu. Nhận diện commit bằng commit message là mong manh, nhất là trong MR khi message có thể bị thay đổi. Commit ID định danh duy nhất một commit, nhưng không phải là định danh hữu ích khi cùng một thay đổi có thể được chuyển sang nằm trên một commit khác. Tuy vậy, trailers là một phần của commit thực sự còn notes thì không, nên với cách dùng trước đây của tôi thì nó không hẳn là giải pháp thay thế tốtTôi tò mò liệu việc đưa thủ công vào commit message và dùng cờ
--trailercó tương đương nhau về mặt chức năng khôngTôi từng thử dựng một instance local và tích hợp với repository host trên GitHub nhưng chỉ thấy nản. Tôi tự hỏi liệu có giải pháp thay thế nào xử lý tốt hơn GitHub các việc như theo dõi thay đổi qua các commit, đồng thời được phát triển tích cực hơn và thân thiện với tích hợp GitHub hơn không. Tôi thật sự ghét công cụ code review của GitHub
Forgejo cũng hỗ trợ từ phiên bản 10 phát hành tháng 1 năm nay: https://forgejo.org/2025-01-release-v10-0/#new-features
https://codeberg.org/forgejo/forgejo/pulls/4753
Trông thật sự rất tuyệt, nhưng tôi tò mò notes hoạt động thế nào với các tính năng viết lại lịch sử như amend hay rebase, vốn thực chất thay commit bằng một bản sao đã chỉnh sửa
Nghe có vẻ notes được gắn với một commit, tree hoặc blob ID cụ thể. Tôi tự hỏi
git rebasevà các lệnh tương tự có đủ thông minh để sao chép notes sang commit mới không, hay chúng cứ biến mất. Cũng thắc mắc chuyện gì xảy ra khi squash nhiều commit thành một trong interactive rebase. Gắn notes vào blob và tree dường như cũng có cùng vấn đề. Nó tạo cảm giác như gắn metadata vào một file hoặc thư mục trong repository, nhưng thực ra là gắn vào nội dung cụ thể. Ví dụ nếu gắn note vào blob chứa chuỗi"Hello world!", Git có liên kết note đó với mọi file có nội dung ấy không? Và nếu đổi một file thành"Hello, world!"thì liệu notes có bị mất không?notes.rewritetronggit-config(1)Tôi có lẽ đã dùng Git khoảng 10 năm mà không biết có git notes. Hay thật
Yêu cầu “mọi forge hãy cho phép dùng offline metadata code review ngay trong Git” có lẽ sẽ không hấp dẫn lắm với các forge thương mại như GitHub. Như chính bạn đã nói, đó là vì rất nhiều giá trị của repository Git đang bị khóa trong các forge như GitHub. Các công ty vì lợi nhuận thường không mấy tích cực trong việc biến giá trị gia tăng của mình thành thứ phổ dụng. Tôi không có ý chỉ trích GitHub; tôi nghĩ họ làm tốt khi cung cấp một dịch vụ tuyệt vời và một gói miễn phí rất hào phóng, đồng thời cho phép trích xuất toàn bộ dữ liệu qua API nếu bạn muốn chuyển đi. Đơn giản đó là bản chất của vận hành thương mại
Git notes chỉ thực sự hay khi bạn thường xuyên thêm văn bản sau khi commit đã được tạo và đã được người khác thấy
Các ví dụ về Acked-By và liên kết tới thảo luận trên mailing list có vẻ không phải ví dụ tốt. Cả hai nhiều khả năng đã được biết khi tạo commit. Thông điệp Git commit thực ra gần như không có giới hạn độ dài, nên cũng có thể sao chép nguyên cuộc thảo luận liên quan đến commit trên forge vào chính thông điệp commit. Một ví dụ tốt hơn, theo tôi, là thêm git note vào một commit sau này bị revert
Có thể tôi hơi lạ, nhưng tôi đã thấy quá nhiều đồng nghiệp không thực sự xem comment hay annotate để nhớ lại vì sao đoạn code ban đầu được viết như vậy. Họ cứ thay đổi ngay và hy vọng vấn đề không bị truy về mình. Nhưng nếu từng phải đối mặt với khách hàng tức giận chỉ chờ bản sửa lỗi, rồi không lâu sau thấy lỗi đó quay lại, bạn có thể sẽ cẩn trọng hơn với việc sửa lỗi. Muốn sửa nhiều bug cùng lúc thường cần refactoring, và refactoring cũng có thể mở ra cơ hội cho tính năng mới hoặc cải thiện hiệu năng
Nếu mục đích là đánh dấu một commit sau này bị revert, thì thông điệp commit tốt hơn. Khi blame một file, bạn sẽ thấy thay đổi mới nhất của file đó; nếu một commit đã revert thay đổi của commit khác, thì commit revert mới hơn sẽ xuất hiện trong blame
Đây không phải là thiếu kiến thức mà là vấn đề UI. Nếu UI của GitHub hiển thị notes, mức sử dụng sẽ lập tức tăng lên rất nhiều
Có nhiều “tính năng hay nhất nhưng không được yêu thích” của Git. Ví dụ như bisect, pickaxe, reflog, range-diff, archive, annotated tags, v.v.
Thật tiếc là nhiều người chỉ nghĩ Git như một dạng Google Drive hào nhoáng hơn, nên các tính năng này thường bị lãng quên
Dù vậy tôi thấy vẫn ổn. Triết lý Unix là tập trung vào một việc và làm việc đó thật tốt
Dự án LibreOffice đã dùng Git notes để theo dõi từng commit trong repository Apache OpenOffice
Khi mirror repository đó thành một branch trong Git repository của LibreOffice, họ ghi lại mỗi commit là thay đổi không liên quan, ví dụ thay đổi hệ thống build mà LibreOffice đã thay bằng thứ tốt hơn từ lâu; là thay đổi trùng với thứ đã có trong LibreOffice; hay trong trường hợp hiếm, là thay đổi được LibreOffice chấp nhận và đã được cherry-pick bằng commit nào. Hiện vẫn có thể xem trực tiếp tại https://cgit.freedesktop.org/libreoffice/core/log/?h=aoo/tru..., và Git frontend này vẫn hiển thị notes. Từ vài năm trước họ đã dừng việc theo dõi các thay đổi như vậy, có lẽ vì tốc độ thay đổi của Apache OpenOffice đã chậm đến mức lợi ích từ việc cherry-pick vài thay đổi ít ỏi không còn đáng kể
Không phải là tính năng hay nhất nhưng không được yêu thích, mà gần hơn với một tính năng gimmick có thể hay trong những trường hợp rất đặc thù, như một team vận hành cả công ty chỉ bằng developer
Những gì cần thiết thì đưa vào thông điệp commit, còn tham chiếu tới ticket trong hệ thống riêng không phải bug mà là feature. Vì JIRA hay các hệ thống khác được dùng để giao tiếp với người không phải developer. Ví dụ, business analyst không hề có quyền truy cập code hay repository, và nhân viên support cũng không truy cập được repository và code. Có thể tạo frontend để người không phải developer xem và chỉnh sửa notes, nhưng như vậy vẫn không có nhiều ý nghĩa. BA, support team, v.v. không quan tâm đến một commit cụ thể; một tính năng có thể khớp đúng với một commit, nhưng thường thì không. Khi dùng nhiều repository và một tính năng trải trên nhiều service, git notes trở nên khá vô dụng, và cuối cùng vẫn cần tham chiếu tới hệ thống bên ngoài
Nhưng đó lại là xu hướng chủ đạo. Thỉnh thoảng analyst của team khác cùng chia sẻ monorepo hỏi tôi những câu mà có thể trả lời ngay bằng một dòng code. Analyst đó khá kỹ thuật và cũng biết SQL, còn code của chúng tôi được viết rất idiomatic và ở mức trừu tượng cao. Dù vậy, văn hóa sẽ không tự thay đổi cho đến khi chết vì những kém hiệu quả nội tại
[^1] https://news.ycombinator.com/item?id=44348438
Một feature request đã 9 năm tuổi yêu cầu GitLab hỗ trợ notes gần đây đã bị đóng: https://gitlab.com/gitlab-org/gitlab/-/issues/15029
Đáng tiếc là cần đăng nhập để đọc, nhưng chắc tài khoản gitlab.com nào cũng được