Gerrit is a web-based code review system built on top of Git. Its primary goal is to make reviewing code changes more efficient and transparent. Gerrit not only hosts your Git repositories, but it also provides a structured workflow for reviewing and approving changes before they are merged into the main codebase. Developers submit changes as “patch sets” and reviewers provide inline comments, suggest edits, and ultimately vote on whether a change should be accepted.
Gerrit’s value lies in enforcing a review-before-merge workflow. Unlike a typical Git workflow where developers commit changes directly into a shared repository, Gerrit makes all changes pass through a review process. This results in cleaner, more maintainable code, increased collaboration, and a shared understanding of the codebase’s direction.
Key concepts and terminology
Change: A single unit of alteration in the code, such as a bug fix or a new feature. In Gerrit, changes correspond to Gerrit’s own internal tracking ID. A change typically consists of one or more patch sets.
Patch Set: Each iterative update to a change is represented as a patch set. If a reviewer requests modifications, you update your code and upload a new patch set. Gerrit keeps the review thread intact and shows the evolution of the change over time.
Project: A version-controlled repository hosted in Gerrit. Projects are often associated with a Git repository on the backend.
Branch: Just like in Git, branches represent parallel lines of development. Gerrit can have multiple branches per project, and changes are generally associated with a specific branch.
Review and score: Reviewers can read the code, make inline comments, and score the changes. Typical Gerrit installations offer scoring ranges like
+2
(Looks good to me, approved) down to-2
(Do not submit), depending on access levels and team policies.Change-Id: A unique identifier that Gerrit uses to tie patch sets together into a single change. This ID is inserted into the commit message and remains the same across all patch sets of a single change.
Submit/integrate: Once the reviewers have given their approvals, the change can be submitted. Gerrit then merges it into the target branch. This ensures that nothing lands in the main branch without explicit review and acceptance.
How Gerrit fits into the workflow
Developer creates a commit in a local repository: The developer makes changes to their code, stages, and commits them locally. Before pushing to Gerrit, the commit message should contain a
Change-Id
.Push the commit to Gerrit for review: Using a special push command (
git push origin HEAD:refs/for/<branch>
), the developer sends the commit to Gerrit’s “for review” branch, triggering the review process.Reviewers provide feedback: Other team members open Gerrit’s web interface, review the change, comment on lines of code, and provide either a positive score (approve) or a negative score (requesting changes).
Developer addresses feedback: If changes are required, the developer updates the code locally and commits again with the same
Change-Id
. Pushing this new commit updates the existing change with a new patch set.Eventually approve and submit: Once reviewers are satisfied and provide the necessary approvals (often a
+2
from a designated reviewer), the change is submitted and merged into the target branch by Gerrit.
Setting up Gerrit (conceptual overview)
Installation: Gerrit can be installed on a dedicated server or hosted service. This typically involves downloading the Gerrit .war file and running it with a supported Java environment. Follow Gerrit’s official documentation to set up your instance. You will also configure Gerrit to point to an existing Git repository or create a new one.
User authentication: Gerrit integrates with a range of authentication providers (e.g., OAuth, LDAP, OpenID). Once users are authenticated, their actions (comments, votes, etc.) are tracked.
Project creation and access control: Gerrit allows granular permissions. Admins can create projects, define who can review, who can submit, and what scoring rules apply. For example, only senior engineers might have
+2
permission, while all developers can comment and give+1
.
Creating your first change**
Step-by-step example:
Prerequisites:
- You have a local Git clone of the repository managed by Gerrit.
- You have the Gerrit server’s URL and you have appropriate permissions to push changes for review.
Process:
Set up Git remote for Gerrit:
Terminalgit clone https://gerrit.example.com/myproject.gitcd myproject# By default, origin points to Gerrit’s repository URL.Make a change: Edit a file, for example
src/App.java
:Terminal// Before:// System.out.println("Hello World!");// After:System.out.println("Hello Gerrit!");Commit your change with a Change-Id: Gerrit requires that each commit includes a
Change-Id
in the commit message. If you don’t already have a commit message hook, you can use Gerrit’scommit-msg
hook, which will automatically generate aChange-Id
for you.Installing the commit-msg hook (one-time setup):
- Download the hook:Terminalcurl -Lo .git/hooks/commit-msg http://gerrit.example.com/tools/hooks/commit-msgchmod +x .git/hooks/commit-msg
Make the commit:
Terminalgit add src/App.javagit commit -m "Change greeting to Hello Gerrit!"After committing, the hook will have inserted a
Change-Id
line at the bottom of your commit message. It will look like:TerminalChange-Id: Iabcdef1234567890deadbeef1234567890abcdef- Download the hook:
Push the change to Gerrit for review: To push your change, you send it to a special Gerrit ref,
refs/for/<branch>
. If the branch you want to submit to ismaster
, do:Terminalgit push origin HEAD:refs/for/masterThis command sends your new commit to Gerrit, not as a direct push to master, but as a review request.
View the change in Gerrit: Go to
http://gerrit.example.com
in your web browser. You should see your new change listed. Clicking on it will show you the diffs, the commit message, and the option to comment.
Reviewing a change
As a reviewer:
Open the Gerrit web interface: When you see a change that needs your review, click on it. The change page shows files that were modified and a side-by-side or unified diff view.
Add inline comments: Click on a line number to comment on that specific line. For example, if there’s a suspicious piece of logic, you might say: “Should we handle the null case here?”
Vote on the change: Depending on your permission level, you can vote
+1
or+2
if you approve, or-1
if you’d like changes before it’s merged. You might also choose0
if you’re just commenting without giving approval or disapproval.Submit or wait for others: If you have the permissions and the change looks good, you can mark it ready for submit. If not, leave it to the designated approvers. Once the required approvals are met, a
Submit
button will appear, and pressing it merges the change.
Updating a change based on feedback
If the reviewer asks for modifications:
Make changes locally: Address the feedback in your code:
Terminal// Previous codeSystem.out.println("Hello Gerrit!");// After changes:if (userName != null) {System.out.println("Hello " + userName + " from Gerrit!");} else {System.out.println("Hello Gerrit!");}Amend the commit: Use
--amend
to add these changes to the same commit (thus preserving theChange-Id
):Terminalgit add src/App.javagit commit --amendWhen you edit your commit message, ensure the
Change-Id
line remains intact.Push the updated patch set:
Terminalgit push origin HEAD:refs/for/masterGerrit recognizes the
Change-Id
and updates the existing change with a new patch set, preserving the review history.
Integrating Gerrit into your workflow
Pre-submit checks: Gerrit can integrate with continuous integration (CI) systems. Changes can be tested automatically before they appear in the reviewer’s dashboard. This ensures that reviewers only look at code that at least passes automated checks.
Branch management: Gerrit can handle multiple target branches. For example, stable branches can have stricter review rules, while a development branch might be more lenient.
Automation with hooks and plugins: Gerrit supports server-side hooks and a rich plugin ecosystem. You can, for example, enforce coding standards or trigger documentation generation when changes are submitted.
Integration with other tools: Many development ecosystems integrate Gerrit with issue trackers (like Jira), chat systems (like Slack), and code analysis tools. This transforms Gerrit into a part of a cohesive DevOps pipeline.
Best practices
Small, focused changes: Keep your changes small and focused. It’s easier to review a small, targeted change than a massive update with multiple unrelated features.
Descriptive commit messages: Write clear commit messages that explain what and why you changed something. This is helpful for both the reviewer and future maintainers.
Respond promptly to feedback: Code review is about collaboration. If a reviewer suggests an improvement, respond to it as soon as possible—either by making the change or explaining why you can’t.
Use Gerrit’s inline comments effectively: Don’t rely solely on the overall change comment. Use inline comments to point directly to the problematic lines. This ensures clarity and reduces back-and-forth.
Understand your project’s policies: Some teams require two
+1
s, or a single+2
from a senior engineer, or a passing CI build. Know these rules so you can ensure your change can be merged quickly once approved.
Summary
Gerrit adds structure and transparency to the code review process. By integrating closely with Git, it provides a seamless system for submitting changes, reviewing diffs, and controlling what ends up in your main code line. Through a combination of web-based review tools, finely tuned permissions, and integrations with CI systems, Gerrit supports efficient, collaborative development. Over time, mastering Gerrit’s review and push workflows, and following best practices, will lead to higher quality code and a more unified development team.