Gerrit code review tool
Gerrit is a web-based code review tool designed for Git repositories.
Code Review Workflow
- Developers fetches code repo form Git repo
- Developer makes changes locally and commits them to their local Git repository.
- Instead of pushing directly to the main branch, the developer pushes the changes to Gerrit for review using a special ref (e.g.,
refs/for/<branch-name>
), where they are stored as pending changes. This is also called Change Request.
$ git push origin HEAD:refs/for/main
- The Change is visible in the Gerrit web interface, where reviewers can inspect the code, leave comments, and suggest improvements and approve or reject them.
- If changes are requested, the developer updates the commit and pushes a new Patch Set to Gerrit. This replaces the previous Patch Set in the same Change.
- Once a change is approved, it can be submit into the target branch.
Rework
- Before making a change, sync with the main repository to ensure there are no conflicts with your change. You can sync your branch because when you created the branch, you set up tracking. While this step is optional, it’s always best to catch and address conflicts early in the code review process.
git pull origin main --rebase
2. After making the fixes to your file (adding the author of the quote), use the --amend
flag to commit the change. This flag ensures that only a single commit will exist, which has the same commit message and Change-Id from the earlier version of the change. A change may go through multiple iterations, created by git commit --amend
. Gerrit tracks them as patch sets.
To add the changed file to the staging area so that it can be committed in Git:
git add <file_name.md>
git commit --amend
Note: If you omitted --amend
, then you created a second (independent) change in Gerrit. You will need to undo it.
3. Before pushing to Gerrit, check the commit information:
git log -1
Verify that your Change-Id is the same as that used in the first code change. You’ll notice that the SHA-1 is new, as it’s unique for all commits.
4. To push your change to Gerrit, run:
git push origin HEAD:refs/for/main
After pushing to the magic Gerrit branch, this commit is now tracked as Patch Set 2 (your first commit is Patch Set 1).
How the Commit is Merged
Single Commit:
- If the Change consists of a single commit, Gerrit merges that commit into the target branch as-is.
- The commit retains its original commit message and metadata.
Multiple Commits:
- If the Change includes multiple commits, Gerrit can squash them into a single commit during the merge process (depending on the project’s configuration).
- Alternatively, Gerrit can preserve the commit history if the project allows it.
Merge Strategies:
Gerrit supports different merge strategies, such as:
- Merge Commit: Creates a merge commit that combines the changes.
- Fast-Forward: Moves the branch pointer forward if the branch has not diverged.
- Cherry-Pick: Applies the commit(s) to the target branch without a merge commit.
Example Workflow
Developer commits changes locally:
git commit -m "Add new feature"
Developer pushes changes to Gerrit for review:
git push origin HEAD:refs/for/main
Reviewers inspect the Change and provide feedback.
Developer updates the Change and pushes a new Patch Set:
git commit --amend
git push origin HEAD:refs/for/main
Once approved, the Change is merged into the main
branch.
Change-Ids
Gerrit needs to identify commits that belong to the same review.
For instance, when a change needs to be modified, a second commit can be uploaded to address the reported issues. Gerrit allows attaching those 2 commits to the same change, and relies upon a Change-Id line at the bottom of a commit message to do so.
With this Change-Id, Gerrit can automatically associate a new version of a change back to its original review, even across cherry-picks and rebases.
Example
$ git log -1
commit 29a6bb1a059aef021ac39d342499191278518d1d
Author: A. U. Thor <author@example.com>
Date: Thu Aug 20 12:46:50 2009 -0700
Improve foo widget by attaching a bar.
We want a bar, because it improves the foo by providing more
wizbangery to the dowhatimeanery.
Bug: #42
Change-Id: Ic8aaa0728a43936cd4c6e1ed590e01ba8f0fbf5b
Signed-off-by: A. U. Thor <author@example.com>
CC: R. E. Viewer <reviewer@example.com>
Creation
Change-Ids are created at commit time on the client side. A standard ‘commit-msg’ hook is provided by Gerrit, and can be installed in the local Git repository to automatically generate and insert a Change-Id line during git commit
, when none is defined yet.
Change Upload
During upload by pushing to refs/for/*
or refs/heads/*
, Gerrit will try to find an existing review the uploaded commit relates to. For an existing review to match, the following properties have to match:
- Change-Id
- Repository name
- Branch name
Amending a commit
When amending a commit with git commit --amend
, leave the Change-Id line unmodified in the commit message. This will allow Gerrit to automatically update the change with the amended commit.
Squashing commits
When squashing several commits together, try to preserve only one Change-Id line, and remove the others from the commit message. When faced with multiple lines, try to preserve a line which was already uploaded to Gerrit Code Review, and thus has a corresponding change that reviewers have already examined and left comments on. If you aren’t sure which lines Gerrit knows about, try copying and pasting the lines into the search box at the top-right of the web interface.
If Gerrit already knows about more than one Change-Id, pick one to keep in the squashed commit message, and manually abandon the other changes through the web interface.
Rebasing a commit
When rebasing a commit, leave the Change-Id line unmodified in the commit message. This will allow Gerrit to automatically update the change with the rebased commit.
Cherry-picking a commit
When cherry-picking a commit, leave the Change-Id line alone to have Gerrit treat the cherry-picked commit as a replacement for the existing change. This can be very useful if the project has a fast-forward-only merge policy, and the submitter is downloading and cherry-picking individual changes prior to submission, such as by gerrit-cherry-pick.
Or, you may wish to delete the Change-Id line and force a new Change-Id to be generated automatically, thus creating an entirely new change record for review. This may be useful when backporting a change from the current development branch to a maintenance release branch.
Happy learning !!!