3 điểm bởi GN⁺ 2025-06-23 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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ả blobtree
    • 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 -m như sau
      git 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ối Notes:
  • 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 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.
  • 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ị trong git log
      git 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

 
GN⁺ 2025-06-23
Ý 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

    • Một tính năng tương tự ở hệ thống khác là PostgreSQL COMMENT: https://www.postgresql.org/docs/17/sql-comment.html
      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
    • Gần đây tôi mới biết GitHub dùng git trailers như một cách thay thế cho việc chèn [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
    • Tôi từng dùng git notes để đánh dấu những commit trên branch của mình đã chạy unit test, và để script bỏ qua các commit đó
      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ốt
    • Thú vị thật, tôi không biết tính năng này. Tôi thích conventional commits, và trailers có vẻ là cách tốt hơn để thêm loại metadata đó
      Tôi tò mò liệu việc đưa thủ công vào commit message và dùng cờ --trailer có tương đương nhau về mặt chức năng không
    • Tôi rất nhớ Gerrit từng dùng khi làm ở GOOG, nhưng xét theo thập niên 2020 thì câu chuyện triển khai của nó khá tệ
      Tô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 rebase và 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?

    • Điều này có thể cấu hình. Mặc định, các thao tác amend và rebase sẽ sao chép notes về phía trước. Xem mục notes.rewrite trong git-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

    • Trước hết cần có một dịch vụ mới lấy tính năng đó làm điểm khác biệt, rồi các đối thủ có thể sẽ thêm lại tính năng ấy để bắt kịp
  • 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

    • Một kiểu thất bại phổ biến là thông điệp commit tự tin tuyên bố đã sửa một lỗi mà thực ra chưa sửa được. Và nó liên kết các lỗi dây chuyền do bản sửa tạo ra vào cùng một bug
      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
    • Thảo luận về commit, tức review và phê duyệt commit (Ack), không thể diễn ra trước khi commit được tạo
      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
    • Thảo luận vẫn có thể tiếp tục sau khi commit đã được tạo
  • Đâ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

    • Tôi ước GitHub hỗ trợ thứ này
  • 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

    • Git notes dù sao cũng bị trùng lặp, vì để theo dõi tính năng cần một công cụ quản lý dự án ở cấp cao hơn. Cần roadmap, phân cấp tính năng, các chi tiết phi kỹ thuật; cứ nghĩ đến các tracker lớn hoặc Jira là được
      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
    • Vì trong nhiều trường hợp, những tính năng đó thực ra không hữu ích đến vậy, mà gần giống đồ trang trí quanh các công cụ cốt lõi đóng vai trò lao động chính
    • Tôi tưởng mình sẽ biết hết các tính năng được liệt kê, nhưng bị pickaxe đánh úp. Có lẽ tôi không nên quá tự tin
  • 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

    • Tôi lại thấy việc business analyst hay nhân viên support không được cấp quyền truy cập code và repository mới là lạ. Lợi ích của việc đối xử với sản phẩm của mình như một hộp đen là gì?
      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
    • Có rất nhiều dữ liệu ngoài commit liên quan nhưng không thuộc về thông điệp commit. Chẳng hạn trạng thái test có pass hay không[1], lịch sử test thủ công, các vòng lặp của code review, hoặc ghi chú để lại khi đào bới một commit gây vấn đề đã hơn 6 tháng tuổ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

    • Cũng có một issue khác với đề xuất hoàn chỉnh hơn: https://gitlab.com/gitlab-org/gitlab/-/issues/216351
    • Nói thêm cho những ai tò mò: nó không bị đóng vì đã hoàn thành, mà bị đóng vì bị bỏ mặc: “Chúng tôi đóng feature request này vì hiện tại trọng tâm không nằm ở lĩnh vực này”