Gerrit/Advanced usage

The basic instructions to set up and operate with Git and Gerrit are described at the Tutorial (see also its shortest version).

Warning
This page mostly documents how to do things "the hard way" in gerrit. The  tool continues to improve, and now contains built-in mechanisms to push to a branch, upload a set of dependent patches, etc. You should probably review  before deciding that you need to proceed further here.

Setup SSH shortcut (optional)
It's easier to access the repository if you don't have to specify the full yourusername@gerrit.wikimedia.org:29418 every time. You can edit your  file and add Host gerrit Hostname gerrit.wikimedia.org Port 29418 User yourusername

Then you can use "gerrit" instead.
 * '' adds a   remote to git which should make this step unnecessary. Cscott (talk)

Howto - Merging your amend back into your branch
''This section is optional. It's offered as a convenience way to offer your a solution to a common problem. At this stage, your new changeset is already in Gerrit.''

After you have amended your change, you may want to merge it back into your local branch.

You can do this by going to the Gerrit change in question.

Here is an example:

https://gerrit.wikimedia.org/r/#/c/7669/4

Go to the Download section and copy cherry pick.

We will select patch set 4.

Switch back to your branch. You will be in your review branch where you just made your change.

Note: use the branch relevant to your change number.

Paste in the cherry pick and merge any conflicts.

Perform a git add on the modified files.

Do not forget to check your status and run a diff.

You should see there are no differences:

Then commit the changes:

Submitting a change to a branch for review ("backporting")

 * Backporting fixes discusses backporting changes to MediaWiki core (coordinate with the MediaWiki Release Manager, handling in Phabricator, etc.)

In this example, we'll backport from   to. The basic idea is to use  to apply the changes from the commit to master to a different branch.

Before you start, look up the git commit hash of the commit that was merged into master. This can be found on the Gerrit change page. Scroll down to the last Patch Set, and the git commit hash is between "Patch Set NN" and "(gitweb)" (not to be confused with the Gerrit Change id which starts with a capital 'I'). Make sure that this commit was indeed merged into the master branch. If it wasn't then wait until it has been reviewed and merged in master &mdash; the commit may still be amended and we don't want to merge an old version).


 * Is there any need to use complicated git push instead of git review here? -- S Page (WMF) (talk) 02:28, 17 May 2013 (UTC)
 * The only reason would be so that you can give it a new topic. So alternatively, after the  check, look up the topic name first (or think of a new topic) and do   then followed by regular   (instead of git push); as of git-review version 1.23, it will reuse the original topic.
 * works too if you want to push to a remote branch from a review branch.

As a result:
 * https://gerrit.wikimedia.org/r/25756 is created for review.
 * shows both the original and the merge changes

Acting on remote branches
By default, your local clone will only have a local master branch set up to track the remote master branch. Tracking means that whenever you fetch objects from the remote repository, git status or git branch will be able to tell you how up-to-date is your local branch, which is very useful. So, whenever you want to regularly act on a remote branch (lets says REMOTE_BRANCH, you want to setup a one locally (REMOTE_BRANCH too to easily remember about it) that track it (with -t).

will give the full details:

Pushing having used automatic setup
From : git-review accepts, as an optional argument, the branch name to interact with. When that argument is not specified, it falls back to look for the defaultbranch parameter in a .gitreview file at the root of the repository.

Every branch should have a .gitreview having a correct defaultbranch value. For mediawiki/core.git, else people will have to use something like:.

Pushing having used manual (Windows) setup
To change where you push to for review having performed a manual setup, run git config alias.push-for-review "push gerrit HEAD:refs/for/BRANCH_NAME" to override the local alias, then use git push-for-review as per usual.

Committing to non master
To make a change to the 1.17 branch, create a branch and tag, and push both:

Partial revert of previous commit
Can be found in gerrit patch view in small letters next to text Patch Set N. Then push for review normally.

SSH and "permission denied (publickey)"
If you get the error Then you're not logged in to your ssh key right now. Solution: do  to make it prompt you for the passphrase for your key and add it to the active keychain. Then you can check what's in your keychain with. Then try pushing for review again.

The fingerprint of the Gerrit server is

dc:e9:68:7b:99:1b:27:d0:f9:fd:ce:6a:2e:bf:92:e1

so you can say yes when it asks you to add that fingerprint to the  file.

Keep in mind that gerrit listens on port 29418 and if for some reason you forgot to specify port number, you might be hitting "normal" SSH daemon listening on port 22 (this one has RSA key fingerprint b5:e9:dc:b2:dd:6e:70:f7:18:8a:dc:a3:5d:ab:99:4d).

To check whether SSH connectivity and public key authentication work you can use:

"[remote rejected] master -> master" and "failed to push some refs"
If push to a branch other than refs/for/master, you will receive something along the lines of:

This means you tried to commit to branch "master" instead of submitting your changes for review.

The following is a similar error where  was trying to push to a non-existing remote branch:

You can see with  what's the branch you're currently using. Try rebasing to push correctly:

"[remote rejected] HEAD -> refs/publish/master/??? (Cannot merge change to another branch)
When attempting to cherry-pick a change or merge an entire branch and then submit for review; gerrit will be very confused if you do not explicitly tell it what branch you're modifying. You might get errors like:

! [remote rejected] HEAD -> refs/publish/master/mwalker_test (change 59546 closed)

or

! [remote rejected] HEAD -> refs/publish/master/mwalker_test (no new changes)

In this case you must ensure that your branch's .gitreview</tt> file has the correct defaultbranch option (e.g. it should be pointing to the branch you're attempting to modify) or you must manually push the refspec using git push gerrit HEAD:refs/for/ </tt>

Email doesn't match
remote: ERROR: committer email address (email) remote: ERROR: does not match your user account.

There are two possible problems that could cause this error. If the email address that git pops back _is_ the email address you intend to use with Gerrit, then you should add that email address in Gerrit, and make sure you click the confirmation link in the email Gerrit sends you. Then try pushing again.

If, however, git sends back some nonsense email (like one you don't use anymore, or a local mail address like root@localhost), you should do the following:

To do it locally for just that repo, instead do:

Then, try pushing again.

Build failed due to merge conflict
After `git review` jenkins-bot emails 'This change was unable to be automatically merged with the current state of the repository. Please rebase your change and upload a new patchset.' This might mean that server master branch now has merge conflicts with your patch.


 * Make sure your master branch hard-reset to the gerrit's master (to avoid git review complaining about multiple commits)


 * Checkout for review, rebase, recommit

If the error occurs even though you have rebased your patch as above, try making an arbitrary change to your commit message, and then running  again (related to ).

Working tree is dirty
Note: if upon doing 'git review' you receive a message "Working tree is dirty" try doing 'git add' for the file(s) changed (or created), then 'git commit', and then 'git review'. This was seen on OSX with an older git client.

missing Change-Id in commit message
Note: if upon doing 'git review' you receive a message about 'missing Change-Id', then your /.git/hooks/commit-msg is probably incorrect. it should look something like:

CHANGE_ID_AFTER="Bug|Issue" MSG="$1"

add_ChangeId { clean_message=`sed -e ' /^diff --git a\/.*/{ s/// q               } /^Signed-off-by:/d /^#/d ' "$MSG" | git stripspace` if test -z "$clean_message" then return fi
 * 1) Check for, and add if missing, a unique Change-Id

You will also get a missing Change-ID message when trying to merge some change from git that does not have. It seems that the hook isn't called by cherry-pick, but it is fortunately called by.

In the example below we will be moving trivial change bd7a268e4be2da23ba0b9943c3b0ba1ac88294dc from git master in the mediawiki/core project (it came via SVN trunk) to REL1_19.

Sample session to exhibit this problem:

(...full trivial diff to one file omitted...)

To fix this, use  (don't commit) option to  : git cherry-pick -n bd7a268e4be2da23ba0b9943c3b0ba1ac88294dc git commit -c bd7a268e4be2da23ba0b9943c3b0ba1ac88294dc

Unfortunately, if you want to add the original commit ID to the message (as done by ) you have to add it yourself.

The change above has been submitted as 3c88c61f1b7e36d5d374a42bb0f50783ab5391a4 for  review.

Don't push
If you attempt to do 'git push' after doing 'git commit' you may receive a response 'Everything up-to-date'. You have not pushed to the branch. You have to do 'git review' to move your changes to gerrit, and only from gerrit will the branch be updated. This seems to be a side effect of checking out master as a branch as of February 2012.

In some projects (e.g. test/) it is possible to do 'git push' instead of 'git review' and have the push succeed. It is probably better not to do that, as it confuses those who find your changes later and don't know where they came from.

git review complains about multiple commits
If git review</tt> asks you if you really want to submit multiple commits, and lists a bunch of unrelated commits from different branches, try this:

git fetch --all git remote update


 * Or better yet, use  to "Skip cached local copies and force updates from network resources". --Cscott (talk)
 * If the error persists, git rebase -i origin/master usually fixes everything just by following instructions on screen.

git review</tt> doesn't like merge commits
If you merged a development branch, and now want to submit a merge commit to Gerrit, git review</tt> may not let you. It may ask you for submitting lots of changes from one of the merged branches, or otherwise mangle the commit. To avoid this, push the commit directly to Gerrit, bypassing git review</tt>:

git push gerrit HEAD:refs/for/master

For more information, see the Gerrit documentation.

Tagging an extension doesn't work
If you want to tag your extension, you need to connect to gerrit using ssh, not https. In your .git/config, the remote url should look like this:

To tag an extension, use git tag followed by git push :

Unlink bogus dependencies (rebase changes)
Example for https://gerrit.wikimedia.org/r/#change,5154

git fetch --all # To make sure we have latest changes git review -d Ie6e3c9be git rebase -i gerrit/master # Delete the commits you want to get rid of git commit --amend # Add a note git review -f # -f deletes the branch after submit

Create a dependency
If you are about to create a patch that depends on another (unmerged) patch, or if you already submitted a patch but need to fix the dependency (i.e. currently it is based on master and would break if merged without the dependency, or maybe you squashed your change on top of the dependency). Then this is the section you're looking for. If you want to fix the patch to have the right dependency rather than to create a new patch with a dependency, then make sure your working copy is clean (no uncommitted changes).

git fetch --all # Make sure we have latest info from the repository git review -d 1234 # Gerrit change number of the change you want as dependency ("parent")

Now we need to make sure the patch has the correct git-parent. Depending on whether you are creating a new patch or fixing an existing patch, there is two different ways to do this. If you are starting fresh: git checkout -b bug/1234 # Creates a new branch, with the current branch (the dependency) as parent git add someFile.php some/other/file.js git commit # Commit your patch
 * 1) Edit files: make your changes

git log -n5 --decorate --pretty=oneline # Verify that the last 5 entries of the log now start with:
 * 1) * (HEAD, bug/1234) your change
 * 2) * (review/john/700) the dependency
 * 3) * (gerrit/master)

git push gerrit HEAD:refs/for/master # Use this instead of `git review`
 *  works fine as the last line here. no need to use  . Cscott (talk)

If you need to amend your patch to have the correct dependency: git branch # Take note of the review/* branch that was created for this, it has an "*" in front of it git checkout bug/1234 # Check out the local topic branch of your change git rebase review/john/7000 # The branch name of the gerrit change we checked out earlier


 * 1) Resolve conflicts if needed,
 * 2) - use "git status" to see the files that need resolution
 * 3) - after fixing it in your editor, "git add filename" for each of the fixed files

git rebase --continue

git log -n5 --decorate --pretty=oneline # Verify that the last 5 entries of the log now start with:
 * 1) * (HEAD, bug/1234) your change
 * 2) * (review/john/700) the dependency
 * 3) * (gerrit/master)

git push gerrit HEAD:refs/for/master # Use this instead of `git review`
 * Again, just use  for the last line. Cscott (talk)

The  directly will make sure that the dependency is kept and the other revisions that are already in gerrit will not be re-submitted.
 *  is smart enough not to touch the already-present revisions. Cscott (talk)


 * The  option to   is an easier way to do this. Cscott (talk)

Splitting a commit in smaller one
Explained in detail at Gerrit/split a submitted change.

Working on an existing change set
Sometimes you want to work on a change set started by some else and then upload your changes as a new patch set. NOTE: DO NOT use the  flag to specify a commit summary: that will override the previous summary and regenerate the Change-Id. Instead, use your text editor to change the commit summary if needed, and keep the Change-Id line intact. (See : )

Viewing and commenting on code
The basic functionality is explained in the Git and Gerrit tutorial.

Some extra bits:


 * Old Version History dropdown menu. This menu will allow you to change what changes you're reviewing. This is helpful if you reviewed a past changeset, and want to make sure your changes were taken into account. Rather than reading through the entire changeset diff'd against the base commit, you can read only the differences between the current changeset and the changeset you reviewed. There's a bonus, too: You can see your comments on the left hand side of the If there was a rebase commit, there will be garbage in the diffs, but you can read things one changeset at a time and it will still be faster.
 * Diff All Unified button:
 * Opens the diff(s) in a new tab. You can double-click on a line and comment on that line, then save a draft comment! Then, click "Up to change" to go back to the changeset.
 * For commits that contain whitespace changes (i.e. indent a block that was changed), it is best to set the diff-preferences appropriately to make it easier to review. When viewing a diff, on top there is a link "Preferences". Then there is two important settings to focus on. "Ignore Whitespace" and "Intraline Difference". The last one (Intraline Difference) is especially useful if a block of code was indented, as this setting will show the added tabs themselves allowing other changes to be recognizable without having to compare every word in your mind (see screenshot).

How to comment on, review, and merge code in Eclipse
As an alternative to Gerrit's web interface, you can also review code from Eclipse using the Mylyn task-management framework. To get started, download and install Eclipse, and then install Mylyn from the Install New Software menu (as of Oct 5th, 2013 you need the snapshots update site to use the Wikimedia Gerrit installation). When you next launch Eclipse, you'll be prompted to add a task for Mylyn. From there, you'll need to install the connector for Gerrit, specify  as the server URL, and add your username and password.

How to review and merge code via command line
Using dippy-bird you can easily do command line review and merging. The query parameter is the change you want to deal with.

You can therefore use that to approve a range of commits:

My change had a "path conflict", how do I rebase / merge it?
For the impatient:

<div style="border:2px padding:1em,2em;"> git checkout master git pull git-review -d <change #> git rebase origin/master git status <edit "both modified" files in status report> git add git rebase --continue git review

Full explanation


So you have submitted a change and was approved. But by the time it gets reviewed other commits have altered the main repository which now cause a conflict. Gerrit is unable to automatically merge your change into the repository, you will have to fix it and resubmit the change.

The example below is based on a real use case : change 2514 using the operations/puppet repository

First fetch the change using git-review and its -d</tt> option :

(production)$ git-review -d 2514 Downloading refs/changes/14/2514/1 from gerrit into review/hashar/ignore_pyc Switched to branch 'review/hashar/ignore_pyc' (review/hashar/ignore_pyc)$

hashar</tt> is the user name, ignore_pyc</tt> the topic name he gave. Notice how git-review automatically placed you to the branch.

You now have to rebase on top of the main branch. The change on gerrit shows the branch, just add "gerrit/" in front. For this change in the operations/puppet repo, the main branch is "production", so rebase on gerrit/production; for other repos it's usually origin/master</tt>.

(review/hashar/ignore_pyc)$ git rebase gerrit/production First, rewinding head to replay your work on top of it... Applying: pyc files are now ignored Using index info to reconstruct a base tree... Falling back to patching base and 3-way merge... Auto-merging .gitignore CONFLICT (content): Merge conflict in .gitignore Failed to merge in the changes. Patch failed at 0001 pyc files are now ignored When you have resolved this problem run "git rebase --continue". If you would prefer to skip this patch, instead run "git rebase --skip". To check out the original branch and stop rebasing run "git rebase --abort". (no branch)$

The key in the above output is the line starting with CONFLICT. It tells you the filename that git couldn't cleanly rebase, usually because your patch alters it and changes in the main branch have also altered it. Running git status confirms it:

(no branch)$ git status (no branch)$
 * 1) Not currently on any branch.
 * 2) Unmerged paths:
 * 3)   (use "git reset HEAD ..." to unstage)
 * 4)   (use "git add/rm ..." as appropriate to mark resolution)
 * 5) 	both modified:     .gitignore
 * 1) 	both modified:     .gitignore

Edit the conflicting file (in this case .gitignore). This will have,     markers surrounding the conflicting lines, you must clean this up. During the merge conflict git creates file.BASE.xxx</tt>, file.LOCAL.xxx</tt>, and  file.REMOTE.xxx</tt> files with the three source versions. You can use a three-way merge tool to pick which lines to use; git mergetool wraps the use of a merge tool.

Once you have finished editing, you have to add that modification to have it used during the rebase then continue fixing any conflicting patches:

(no branch)$ git add .gitignore (no branch)$ git rebase --continue Applying: pyc files are now ignored (review/hashar/ignore_pyc)$

Since there was no more patches to fix, you have been placed back in the review/hashar/ignore_pyc branch. Looking at the log:

$ git log -n5 --decorate --pretty=oneline ...
 * a3631d2 (HEAD, review/hashar/ignore_pyc) pyc files are now ignored (2 seconds ago
 * 1b6cd67 (gerrit/production, production) ensure sample config file removed (18 hours ago)

Verify you change looks fine before resubmitting it to gerrit. Just use git show, i.e. git show a3631d2</tt>. You can eventually amend it to state you have rebased the change.

Now submit your change back in the repository:

(review/hashar/ignore_pyc)$ git review remote: Resolving deltas:  0% (0/2) To ssh:// @gerrit.wikimedia.org:29418/operations/puppet.git (review/hashar/ignore_pyc)$

Heading back to Gerrit, the change is a new patchset pending review:



Congratulations on fixing your first rebase / merge conflict!

Your change requires a recursive merge to resolve
If you get the error "Your change requires a recursive merge to resolve", you need to rebase the change set against master.
 * 1) Make sure your master branch is up to date: <tt>git pull origin master</tt>
 * 2) Create and switch to a new branch in which to checkout the change set with the conflict: <tt>git checkout -b BRANCHNAME</tt>
 * 3) Checkout the conflicting change set into this branch. You can copy/paste the correct command from the 'Download' section in the Gerrit review. It will look something like this: <tt>git fetch ssh://awjrichards@gerrit.wikimedia.org:29418/mediawiki/extensions/MobileFrontend refs/changes/14/3414/3 && git checkout FETCH_HEAD</tt>
 * 4) Rebase against master: <tt>git rebase master</tt>
 * 5) Push the change to Gerrit for review: <tt>git review</tt>
 * 6) Re-review the change set in Gerrit, and then submit the changes to be merged to master.

Your change isn't merged
If someone enters +2 Code Reviewed, it should trigger a series of automated builds and tests. Continuous integration/Workflow describes the flow.

In Gerrit, the "user" jenkins-bot should add a comment
 * Starting gate-and-submit jobs. https://integration.wikimedia.org/zuul/

Follow the link to see the progress of the tests for your change that Zuul has submitted to Jenkins.

If you don't see the "Starting gate-and-submit jobs" comment in gerrit, look at https://integration.wikimedia.org/zuul/ It shows everything that Zuul has submitted to Jenkins, and the "Queue length" number on top is the number of events not yet processed. If your job doesn't appear below this on the page below but the queue length is non-zero, it is likely in the queue; Zuul and Jenkins are probably busy and you just have to wait. But if the queue length is 0 and your change doesn't appear, it means it isn't going to happen and you need to resubmit it. Note that new repos have to be manually added to jenkins-bot's list.

If the required tests all pass (note that some are "non-voting"), then jenkins-bot will add a comment "Build succeeded" followed by "Change has been successfully merged into the git repository."

You need to override Jenkins
First of all, you should more or less never do this. (So far the reason was backporting a change to an old release that had broken tests). If Jenkins has a -2 you generally can't merge the change. What you need to do:
 * Removing the jenkins-bot "Verified" review (click the )
 * Review the latest patch set with "Verified +2" in addition to "Code-Review +2" (this is normally reserved for Jenkins, but since we're overriding it we're replacing its score with our own)
 * Click "Publish and Submit"

How to create a repository ("Gerrit project")
See "Request a new Git repository". There's a form to fill out. It should get processed very quickly (within a couple of days).

Code Review links
Links to old SVN Code Review revisions are stored in commit notes. They may be fetched for display in the git log using the following command:

Note this must be done separately for each git repository.

Gerrit review scores
As above, code review metadata is stored in commit notes and may be fetched using:

To retrieve them regularly, add to your git config.

To display them in  (similar syntaxes work for related tools):

ssh proxy to gerrit
If gerrit is being slow, when it comes to uploading patches, it might be a network issue. (especially if you are in Europe, at certain times of the day) If you have a server / vm in the US or other proxy that you can use, then you can access gerrit via that.

In your ~/.ssh/config add something like:

Then connect to the proxy (e.g. via ssh, with the "-D 8081" option). Then it should work to access gerrit to upload / download patches and may be faster.