Ý nghĩa của Change-Id trong Gerrit Code Review

    Những anh em nào đã làm việc với Gerrit Code Review thì đều sẽ biết về Change-Id, nhưng bản chất của nó là gì, dùng để làm gì thì có thể có nhiều ae vẫn chưa hiểu rõ. Trong bài viết này mình sẽ chia sẻ về bản chất và ý nghĩa của Change-Id trong Gerrit Code Review.


Trong các dự án mà dùng Gerrit Code Review thì thường sẽ cấm developer push thẳng commit lên git repository (trừ những người được phân quyền) mà phải push lên Gerrit để qua review và CI build, OK mới được các leader submit (merge) lên repository.

Và để Gerrit có thể nhận dạng được một commit là commit mới hoàn toàn hay là commit để update tiếp cho 1 commit trước đó đã đưa lên Gerrit để review thì một commit message cần phải có Change-Id trong đó. Một ví dụ rất cơ bản, tôi tạo một commit hoàn toàn mới và push lên Gerrit, và commit đó của tôi có Change-Id là ‘abcd1234‘. Khi leader của tôi review cái Change đó của tôi ( khi push lên gerrit thì sẽ được gọi là Change ) thì thấy chưa OK → tôi phải update lại code và tạo tiếp một commit với option –amend. Lúc này commit mới sẽ giữ nguyên Change-Id trong commit message và khi được push lên Gerrit thì Gerrit sẽ nhận dạng được rằng commit mới này thuộc cùng 1 Change với commit lúc trước và sẽ nhóm lại vào cùng 1 link với commit lúc trước dưới dạng patchset mới.

Change-Id được tạo ra lúc commit ở phía client. Một ‘commit-msg‘ hook chuẩn sẽ được cung cấp bởi Gerrit và có thể được install vào local Git repository bằng command: Hoặc Hoặc cũng có thể copy bằng tay vào folder .git/hooks ( ví dụ: myproject/.git/hooks) Nếu ở trên môi trường Linux thì cần cấp quyền execute:

commit-msg‘ hook sẽ tự động được run khi chúng ta tạo commit mới, nó sẽ tự động tạo ra một dòng Change-Id và chèn vào cuối của commit message do Git tạo ra. Còn nếu commit với option –amend thì Change-Id sẽ được giữ nguyên giống với Change-Id của commit cuối cùng. Change-Id không phải là unique trên Gerrit mà nó chỉ unique trên mỗi branch của mỗi repo. Tức là Change-Id của các branch khác nhau của cùng 1 repo vẫn có thể trùng nhau.

Khi chúng ta push commit lên thì đầu tiên Gerrit sẽ cố gắng tìm một Change đã có tương ứng với commit đó. Một Change có sẵn sẽ được coi là tương ứng với commit đó nếu trùng cả 3 thống số sau:
  • Change-Id
  • Repository name
  • Branch name

Nếu tìm thấy Change tương ứng thì Gerrit sẽ update patchset mới vào Change đó, nếu không tìm thấy thì Gerrit sẽ tạo change mới.

Một Change ở trên Gerrit sẽ luôn có Change-Id

Ví dụ một Change có nhiều patchset

Thông thường thì Gerrit sẽ được cấu hình để chặn không cho push các commit thiếu Change-Id trong commit message. Nếu cấu hình bỏ chặn thì khi push commit lên Gerrit sẽ tự động thêm Change-Id vào trước khi tạo Change trên web.


Vậy có một câu hỏi là tại sao mỗi commit đều có commit id tạo ra bởi Git thì tại sao Gerrit không dùng luôn cái này để identify commit mà phải dùng Change-Id ?

Commit id là một hash string được tạo ra bởi git tool và nó sẽ bị thay đổi khi chúng ta rebase, cherry-pick, hay thậm chí kể cả commit –amend. Do đó không thể dùng commit id thay cho Change-Id được.

Hy vọng bài viết này giúp được anh em hiểu thêm về Change-Id và có thể dùng Git, Gerrit một cách tự tin và hiệu quả hơn.

 

— Phạm Minh Tuấn (Shun) —