This guide provides a brief guide to creating Git commits and getting them reviewed on Gerrit, for those who have not used either system before. It assumes that you’ve already got a local copy of the repository you want to modify, and have set up your Gerrit credentials. For more details on the topics that this guide skims over (such as the commit queue and the review process) see the Contributing Guide.
We’ll be talking about two related but separate systems here:
Git is a version control system, in many ways similar to SVN, except that Git repositories do not need to be hosted on one central server; instead, you have a local copy which can pull from many servers, called remotes. It's strongly recommended to read this introductory presentation for more in-depth information including an explanation of the concepts and workflows.
Gerrit is a Git remote which hosts the code and makes it easier to manage code reviews. Many different projects host instances for their code, but mostly I’ll be referring to the Chromium Gerrit instance when I mention it here. For more details, see this introductory presentation that goes into more detail about the concepts and workflows.
In your local copy of your repository, make some changes, then run
git status. Here’s some sample output (in this example we'll be committing some files in the
$ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: foo.txt Untracked files: (use "git add <file>..." to include in what will be committed) chip/max32660/ no changes added to commit (use "git add" and/or "git commit -a")
This output tells us that a file that Git already tracks (
foo.txt) has been modified, and a directory has been created that Git hasn’t seen before (
chip/max32660/). We need to create a commit that contains these changes. To do that, we first tell Git what we want to include in this commit:
$ git add chip/max32660/build.mk $ git add chip/max32660/max32660.h …
Now, when we run
git status, we see that some changes have been added. (In Git terms, we say that they are staged.)
$ git status On branch master Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: chip/max32660/build.mk modified: chip/max32660/max32660.h Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: foo.txt Untracked files: (use "git add <file>..." to include in what will be committed) chip/max32660/foo.h chip/max32660/foo.c ... no changes added to commit (use "git add" and/or "git commit -a")
We’re almost ready to make a commit, but notice that we’re currently on the branch called
master. Most changes end up on
master eventually, but for now we want to put them on a different local branch (often called a feature branch) while they’re in review. So, let’s create one called
max32660-basics and switch to it:
$ git checkout -b max32660-basics $ git status On branch max32660-basics ...
Now we can make the commit. When you run this command, a text editor will appear:
$ git commit
In the editor, add a message for your commit. See the Commit messages section of the Contributing Guide for suggestions on what to put in it. (No need to add the
Change-Id line shown there, Gerrit will do that for you.)
When you’re done, save the file and close your editor. The commit has now been made. (You can see it in
Now you’ve got a branch with a commit in it, and you want to upload it to Gerrit for review. Gerrit’s unit of code review is called a changelist (often abbreviated to CL), and you can create one from your branch. First, let’s make sure that you have Gerrit set up as a remote.
If you downloaded the repository by using
git clone or
repo, you probably already have Gerrit set up as a remote. Check with the
git remote -v command, and note the name of the remote (
cros in this case):
$ git remote -v cros https://chromium.googlesource.com/chromiumos/platform/ec (fetch) cros https://chromium.googlesource.com/chromiumos/platform/ec (push)
If you don’t see a suitable remote, you can add one (replacing
platform/ec with the appropriate path for the repository you're working in):
$ git remote add cros https://chromium.googlesource.com/chromiumos/platform/ec
First, check that you’re on your feature branch by running
git status and checking the first line. (If you’re on the wrong branch, use
git checkout <branch name> to get back to the right one.)
You‘ll need the
repo command for this step.
repo is a tool that makes it easier to manage multiple related Git repositories, but we’ll just be using it to upload our change and run presubmit checks. If you don't have it, you can get it by installing
First, set your branch’s upstream. This tells
repo what version of the code it should compare your current state with. You’ll probably want the following command (assuming that your remote is called
$ git branch --set-upstream-to=cros/master
Now you can tell
repo to upload your change:
$ repo upload . --br=max32660-basics
When asked whether to run the checks, enter
yes. If the checks find any problems, they will tell you about them and the change will not be uploaded. Once you‘ve fixed them you can run the command again. Sometimes it will warn about things that can’t be fixed given the circumstances, in which case add
--ignore-hooks to the command (though you should probably amend your commit message to explain why).
Whichever method you use, you should see some output like this if all goes well:
Upload project src/platform/ec/ to remote branch refs/heads/master: branch max32660-basics ( 1 commit, Wed Jun 5 12:14:47 2019 -0700): 7d244dd1 Add basic support for MAX32660 to https://chrome-internal-review.googlesource.com (y/N)? y remote: Processing changes: refs: 1, new: 1, done remote: remote: SUCCESS remote: remote: https://chrome-internal-review.googlesource.com/c/chromeos/platform/ec/+/1234567 Add basic support for MAX32660 [NEW] remote: To https://chrome-internal-review.googlesource.com/chromeos/platform/ec * [new branch] max32660-basics -> refs/for/master
Here, the URL
https://chrome-internal-review.googlesource.com/c/chromeos/platform/ec/+/1234567 is the one for your change. Open it in your browser to see the change.
Now, if you’re signed in to Gerrit, you can request that one or more other Gerrit users review the CL. Click “Reply” and add the reviewers you want to the “Reviewers” line.
Once you’ve sent your CL for review, your reviewers will probably leave comments on it, suggesting improvements. Once you’ve made the changes they asked for, you need to update the CL in Gerrit.
To do this, we need to modify the commit you created the CL from. First, let’s check that the commit has the Change ID line that Gerrit uses to identify it. Run
git log and look for a line beginning
Change-Id: in the message. With that verified, let’s go ahead and modify the commit.
If you haven’t committed your recent changes yet, this is really simple. Use
git add as before to stage the changes, but then instead of creating a new commit, change the existing one:
$ git commit --amend
The commit message editor will appear again, prefilled with your existing message. If you want to change the commit message, do so now (but make sure to leave the
Change-Id: line intact). Then save and close the editor as before.
If you’ve already made additional commits on the branch, all is not lost. We can combine them together after the fact, using a rebase:
$ git rebase -i master
(Yes, that should be
master, even though you’re on a branch, as we’re telling the rebase command to look at all the commits between this branch head and the master branch.)
A text editor should appear, prepopulated with a list of commits, something like the following:
pick 7d244dd12 Add basic support for MAX32660 pick 2e0a4ea43 Fix some review comments pick 46d8c0a28 Fix some more comments # Rebase 29e7e6eec..46d8c0a28 onto 29e7e6eec (3 commands) # # Commands: # p, pick <commit> = use commit # r, reword <commit> = use commit, but edit the commit message # e, edit <commit> = use commit, but stop for amending # s, squash <commit> = use commit, but meld into previous commit # f, fixup <commit> = like "squash", but discard this commit's log message # x, exec <command> = run command (the rest of the line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop <commit> = remove commit # l, label <label> = label current HEAD with a name # t, reset <label> = reset HEAD to a label # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>] # . create a merge commit using the original merge commit's # . message (or the oneline, if no original merge commit was # . specified). Use -c <commit> to reword the commit message. # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
The first line will be your original commit, which we want to combine everything in to. To do that, simply replace
fixup on all the lines below it. Then, save and close the editor. Git will go through and do the combining.
(If you want to change the commit message too, just run
git commit --amend at this point.)
Now that you’ve modified the commit, re-upload it using the same
repo upload command you used before.
Once the upload is done, open your CL in Gerrit again. You should see that it now has another patch set. A patch set is Gerrit’s name for a version of a changelist, and Gerrit allows you (and your reviewers) to see what you’ve changed between patch sets.
To make it easier to see what’s going on, reply to your reviewers’ comments. This is very important to make it easier for both you and your reviewers to keep track of what's happening. If you’ve done what they asked for, click “Done” and Gerrit will mark the comment as resolved. Otherwise you can reply explaining why you think their suggestion won’t work or isn’t a good idea. Once you’re done, click the blue “Reply” button at the top of the page to send your responses.
To be submitted, your CL must have a Code-Review +2 from at least one reviewer, and Verified +1 from anybody (including yourself). Once it has those, reply to the CL adding Commit-Queue +2 to start the submission process. Assuming that the tests pass, you will get an email some time later telling you that the CL has been submitted.
You probably want to build on the code that you just submitted in your next CL. To do this, you’ll need to update your local copy of the master branch to include the changes that have just been merged. Checkout master, then tell
repo to synchronise your repositories:
$ git checkout master $ repo sync
(If you’ve got other stuff going on in your Chromium OS tree, you might find it helpful to split repo sync into two stages.)
If you run
git log now, your CL should appear somewhere in the list. (It might be quite far down depending on how busy the repository is and how long it’s been since it was submitted.) Now you can create another feature branch and start again, building on the changes you’ve already submitted.