Integrating Chromium Commits with Gerrit via git cl upload
This article explains how the git cl upload command from
Chromium’s depot_tools bridges the gap between a
developer's local Git environment and the Gerrit code review server. It
covers the automated workflow of the command, including upstream branch
comparison, local presubmit validation, Change-Id management, local
configuration tracking, and the underlying network operations that
create or update ChangeLists for the Chromium web browser project.
Branch Comparison and Commit Squashing
In Chromium development, a single local Git branch corresponds to a
single ChangeList (CL) in Gerrit. When you run
git cl upload, the tool first determines the diff by
comparing your current local branch against its tracked upstream branch,
which is typically origin/main.
Even if you have made multiple local commits on your working branch,
git cl upload treats the entire branch as one logical
change. By default, it squashes all local commits on that branch into a
single commit payload before sending it to Gerrit, ensuring that
reviewers see one unified patchset.
Local Presubmit Checks
Before transmitting any data to the Gerrit server,
git cl upload runs a suite of local validation scripts
known as presubmit checks. The tool traverses the repository's directory
tree to locate PRESUBMIT.py files relevant to the modified
files in your commit.
These scripts automatically verify that your code adheres to
Chromium's strict guidelines. They check for proper code formatting
(such as git cl format), valid license headers, correct
OWNERS file syntax, and common programming errors. If a
critical presubmit error is detected, the upload process aborts
immediately, forcing you to fix the issue locally before consuming
server resources or reviewer time.
Change-Id Generation and Commit Description
Gerrit relies on a unique identifier called a Change-Id
located in the footer of the commit message to associate multiple
patchsets with the same code review issue.
During the upload process, git cl upload opens your text
editor to allow you to write or edit the CL description, which is
pre-populated using your local commit messages. Once you save and close
the editor, the tool checks for the presence of a Change-Id
line. If one does not exist, git cl generates a unique
SHA-1 hash prefixed with the letter "I" and injects it into the footer
of your commit message, amending your local Git commit
automatically.
Tracking State in the Local Git Configuration
To ensure that future uploads from the same branch update the
existing Gerrit review instead of creating a new one,
git cl stores metadata in your local
.git/config file.
When an upload succeeds, the tool writes the Gerrit issue number, the
server URL, and the base commit hash directly under the configuration
section for your current branch (for example,
branch.<branch-name>.gerritissue). On subsequent runs
of git cl upload, the script reads these values from
.git/config to know exactly which Gerrit issue to target
with the new patchset.
Pushing to Gerrit Refs and API Integration
The final stage of git cl upload is the network
transfer, which combines standard Git protocols with Gerrit's REST
API.
Instead of pushing directly to the main branch,
git cl executes an underlying git push command
directed at Gerrit’s special magic reference namespace:
refs/for/main. Pushing to this target instructs the Gerrit
server to intercept the commit and stage it for code review rather than
merging it into the codebase.
Simultaneously, git cl communicates with the Gerrit REST
API over HTTPS. It authenticates using credentials stored in your local
.gitcookies file and applies metadata to the CL. This API
call sets the patchset title, assigns reviewers (via the -r
flag), adds CC recipients, and can even trigger the Chromium Commit
Queue (via the --use-commit-queue or -d flags)
to begin automated trybot testing immediately upon upload.