Link Search Menu Expand Document

Git with Gerrit

Our Gerrit Code Review site will serve as your main git repository, and will be your home for code reviews.

In all examples on this site, ${USER} should refer to your user name (e.g. USER=joebruin for joebruin@g.ucla.edu), and ${REPO} should refer to your repository/git project name (e.g. REPO=your_team_name).


Table of contents

  1. SSH access
  2. Group setup
  3. Creating a git repository
  4. Access controls
  5. Submitting code for review
  6. Responding to reviews
    1. Editing in a temporary branch
    2. Editing in the Web UI
  7. Pair Programming
  8. Submitting to main branch
  9. Incorporating other changes
  10. Handling merge conflicts
  11. Working with a remote branch other than main
  12. Suggested reading

SSH access

Gerrit serves git projects over SSH on port 29418. If you do not have SSH keys (e.g. ~/.ssh/id_* files), you will need to create some, by running ssh-keygen -t ed25519.

You will need to add your SSH key to Gerrit to access hosted git projects:

  • In the web UI, click the gear icon in the upper right to go to User Settings.
  • Click SSH Keys in the left nav and paste the contents of ~/.ssh/id_ed25519.pub (or equivalent) into the New SSH key text box
  • Click Add new SSH key to complete the process.

You may add multiple SSH keys, for each development environment from which you need to access git repositories.

Group setup

To create a group for your team:

  • In the web UI, go to Browse -> Groups, then Create New
  • Choose a unique group name, and Create.
  • Add members to your group by accessing the Members link in the left nav.

Creating a git repository

For individual repositories, you should prefix the name of the repository with “${USER}-”, since all repositories on code.cs130.org exist in the same namespace. For team repositories, you don’t need the ${USER} prefix, and you can feel free to get creative to avoid name clashes.

To create a repository named ${REPO}:

  • In the web UI, go to Browse -> Repositories, then Create New
  • Fill out Repository name with ${REPO}
  • Enter a group for the Owner field. The web UI will autocomplete valid groups as you type.
    • If this is an individual repository, start typing ${USER} and select the group that looks like “user/Your Name (${USER})”.
    • If this is a team repository, enter your team group name.
  • Leave the remaining defaults and Create.

Click Access in the left nav after creating your project to view access controls. The Owner you set during creation should already show up as having Owner access to Reference: refs/*. If you forgot to set the Owner field above, it will be set to Registered Users, meaning anyone can access and write to your repository. In that case, you can Edit the permissions to set the correct Owner.

Your repository will be available to git over ssh on port 29418:

$ git clone ssh://${USER}@code.cs130.org:29418/${REPO}

Access controls

By default new repositories have the following access controls:

  • Owners can push code for review, but cannot push directly to the main branch without review. Only site administrators (instructors, TA’s) can push directly to main and skip creating reviews.
  • Only owners can read, create reviews, and submit code to repositories.

If you’ve created an individual repository (with only yourself as owner), then you’ll want to add access for select others to view/review your code:

  • In the web UI, go to Browse -> Repositories and select your repository
  • Click Access in the left nav
  • Click the Edit button
  • In the Reference: refs/* section, next to Add permission select Read, then click Add
  • In the newly created Add group box, type your reviewer’s name, which will autocomplete to “user/Their Name (username)” and allow you to add
  • Do not enable the Exclusive option, as this prevents default permissions from being inherited. Doing so would prevent graders from being able to see your repository and code changes.
  • Click Save to put your access change into effect

Submitting code for review

Before starting work on a feature, you should create a new git branch, assuming the code does not depend on anything outside of the main branch. Features should be small enough that you can make a small number of commits (ideally 1) before sending code out for review. When you’re ready to send your commit(s) for review, you run git review:

$ git checkout -b my_feature

… edit your code, then:

$ git add .
$ git commit -m "Wrote a bunch of code"
$ git review --reviewers my_reviewer

This will create a review visible on the CS130 Gerrit site, the URL of which will be printed to the console. You can verify in the web UI that your reviewer was correctly added to the change. Note that your reviewer needs to have Read or Owner access to the repository (either explicitly or by group membership) in order to actually review your code. You can also add reviewers from the Web UI, which will only allow you to add reviewers who actually have read access.

If you have created multiple commits before sending for review, or have already send a commit for review and want to create a new one, you will be prompted, Do you really want to submit the above commits? Go ahead and enter yes to create multiple reviews, or an additional review on top of an existing review. Gerrit will be smart enough to link them together, and submit them in the proper order.

If you don’t expect to make any more commits / send more reviews within this feature branch, such as when you’ve completed a feature, you can run git review -f when sending your review to also delete the local branch.

Responding to reviews

Once your reviewer responds to your initial patch set (review request), you’ll probably need to edit your code to address their comments. There are a couple ways to do this.

Editing in a temporary branch

You can use git review to pull your latest patch set for a given change ID from the server and create a new temporary branch in which you can make all your edits. When you’re done, you can amend your previous commit, then upload the patch to your review thread. First view your changes and get a change ID:

$ git review -l
$ git review -d my_change_id

… edit your code, then:

$ git add .
$ git commit --amend --no-edit
$ git review -f

Note it’s important to use the --amend flag with git commit, to avoid creating a new commit (which would create a new ChangeId in the commit text, and would be bad). Gerrit uses change IDs to uniquely represent changes, so if you create a new commit instead of amending a previous one, you will also create a new review thread in Gerrit instead of modifying your existing one.

Also note we’re using -f with git review to delete this branch, since it was only created by git review for the purpose of responding to a given round of review.

Editing in the Web UI

If your edits are minor or straightforward, you can edit them in the UI. You won’t be able to compile or test your changes, so save this method for updates to comments or documentation where you’re absolutely sure you won’t be breaking any code. (But can you really be that sure?)

To begin, navigate to the change in the Web UI, and click Edit in the upper right to enter edit mode. To edit a particular file, click the Actions dropdown next to the file in the Files table, and then click Open to open the file editor. Make your edits, then click Save and then Close. When you’re finished editing, click Publish Edit from the main change page to upload a new patch set with your changes.

Pair Programming

Developing your software alongside another of your teammates in person or over video conference with screen sharing is allowed. However, you still need to show work in Gerrit through a review mechanism and patchset. Additionally, one person should not write all the code. To avoid losing points on your assignments, make sure to show proof of your back-and-forth dialog in the same way as if you were remote.

Submitting to main branch

Once you’ve gotten a +1 approval on your change, you should submit through the Gerrit UI with the Submit button. If successful, your code will then be integrated into the main branch.

Incorporating other changes

As you work on a change, the codebase will be changing as other people (or even you) submit changes through Gerrit. You can pull the latest changes from Gerrit into your local repository so that you are working on a relatively up-to-date version of the code. Doing this frequently will help reduce the frequency and severity of merge conflicts, which require special handling.

Let’s assume you are working in a branch my_feature and you want to incorporate some submitted code:

  • If you have uncommitted changes, stash them:
    $ git stash
    
  • Switch back to the main branch and get it up to date:
    $ git checkout main
    $ git pull --rebase
    
  • Rebase your feature branch (e.g. my_feature) on to main:
    $ git rebase main my_feature
    
  • If you had uncommitted changes, apply them:
    $ git stash pop
    

If there were no changes made near the lines of code you’ve edited, the changes should apply cleanly. If someone changed a line of code that you’ve also edited, then you may have a merge conflict.

Handling merge conflicts

Sometimes multiple pending changes will reference the same file. In many cases, Gerrit can merge the changes cleanly, and handle merges for you. In some cases, such as when the same line is being changed, or the resulting merge is ambiguous, Gerrit will detect a Merge Conflict. Changes with a merge conflict will be flagged in the UI, and if conflicting code has been submitted in another change, your change will not submit.

When this happens, you will have to resolve the merge conflict and update your change before submitting by getting your main up to date, rebasing your feature branch onto main, resolving the conflict, and updating your review:

  • Get main up to date:
    $ git checkout main
    $ git pull --rebase
    
  • Rebase your feature branch (e.g. my_feature) on to main:
    $ git rebase main my_feature
    
  • Show files with merge conflicts:
    $ git status
    
  • Edit the conflicting files and continue the merge. You may need to repeat this step multiple times if you have multiple pending reviews out. After editing files:
    $ git add .
    $ git rebase --continue
    
  • Update your review(s)
    $ git review
    

Working with a remote branch other than main

If you are performing a series of changes that need to deviate from the main branch, but still want to get them reviewed, you may create a remote branch on Gerrit and push changes to that remote branch. Then, when your series of changes are done and your branch is in a good state, you can merge it back to main. This process may be useful for a large refactoring where you want to keep the main branch in a good state while your refactoring branch may get a little messy. Here is an example workflow:

  • Browse to your repository on Gerrit, and then navigate to the Branches page.

  • Click Create New and enter a Branch name, e.g. refactor. Leaving Initial Revision blank will base this branch off the current main. Click Create to create the remote branch.

  • Sync your local git repository to pick up the remote branch.
    $ git fetch
    From ssh://code.cs130.org:29418/test
    [new branch]      refactor   -> origin/refactor
    
  • Create a new branch (e.g. my_refactor1) in your local git repository that tracks the remote refactor branch:
    $ git checkout -b my_refactor1 origin/refactor
    Branch 'my_refactor1' set up to track remote branch 'refactor' from 'origin'.
    Switched to a new branch 'my_refactor1'
    
  • Make some code changes, and send for review with the --track argument, or with refactor as the remote branch argument. You may optionally verify with --dry-run that the change will be pushed to the refs/for/refactor remote branch:
    $ git review --track --dry-run # OR git review refactor --dry-run
    Please use the following command to send your commits to review:
          git push origin HEAD:refs/for/refactor%topic=my_refactor1
    
    $ git review --track -f # OR git review refactor -f
    remote: ... SUCCESS ...
    To ssh://code.cs130.org:29418/test
    [new branch]      HEAD -> refs/for/refactor%topic=my_refactor1
    Switched to branch 'refactor'
    Deleted branch 'my_refactor1'
    
  • Remember to use git review --track if you are uploading additional patch sets after running git review -d and amending your commit.

  • After your series changes to the remote refactor branch are submitted in Gerrit, you should create a change in your local main branch to merge the remote branch and send for review. This change will contain all the files previously submitted to your refactor branch since it diverged from main. Note you should include --no-ff to avoid a fast-forward merge so that Gerrit has a real merge to review. Failure to include this will result in an error when running git review. (If you make a mistake, try git reset --hard origin/main.)
    $ git checkout main
    Switched to branch 'main'
    Your branch is up to date with 'origin/main'.
    
    $ git fetch # OR git pull --rebase
    ...
    
    $ git merge origin/refactor --no-ff
    Merge made by the 'recursive' strategy.
    ...
    
    $ git review
    remote: ... SUCCESS ...
    To ssh://code.cs130.org:29418/test
    [new branch]      HEAD -> refs/for/main
    
  • After successfully merging you should delete your remote refactor branch. (Future refactorings should use a new branch, preferably with a different, more descriptive, name.) Navigate to the Branches page of your repository on Gerrit, and click Delete next to the refactor branch in the table.

Suggested reading


Back to top

“You may think using Google’s great, but I still think it’s terrible.” —Larry Page

Page last modified: June 3, 2024.