1 .. _lfreleng-docs-gerrit:
7 Gerrit is an opensource web-based collaborative code review tool that
8 integrates with Git. Gerrit provides a framework for reviewing code commits
9 before it merges into the code base.
10 The changes are not made a part of the project until a code review completes.
11 Gerrit is also a good collaboration tool for storing the conversations that
12 occur around the code commits.
16 Here is more information on `Gerrit <https://www.gerritcodereview.com/>`_
21 Before you get started, you should have:
23 * an LFID account (sign up `here
24 <https://identity.linuxfoundation.org/>`_)
25 * git installed (see: http://www.git-scm.com/downloads)
26 * git configured with your name, e-mail address and editor
30 git config --global user.name "Firstname Lastname"
31 git config --global user.email "email@address.com"
32 git config --global core.editor "text-editor-name"
34 .. note:: Your name and e-mail address (including capitalization) must match what you entered
35 when creating your LFID account.
37 * an ssh public/private key pair (see the good `GitHub docs on generating ssh keys
38 <https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/>`_)
40 * register in the Gerrit server. See below for detailed instructions.
41 :ref:`register-key-gerrit`
43 * git-review installed (see: https://www.mediawiki.org/wiki/Gerrit/git-review#Installation)
48 Cloning the code into a local workspace can happen via HTTP or SSH.
50 #. Make sure your Gerrit settings are up to date with correct SSH and GPG keys.
52 #. In the project's Gerrit instance, we can see the HTTP and SSH commands. From
53 the left side menu, select Projects->List->Select any project->General.
55 #. Copy the desired clone command and paste it in your terminal.
60 This option provides a more secure connection. We should always use SSH for
61 pushing code unless the user is under a network that prevents SSH usage.
62 In such case, use HTTPS.
66 For more information on how to generate the public/private key pair see
67 `Generating SSH keys for your system`_ and
68 `Register your SSH key with Gerrit`_
72 The SSH clone option will not appear if the settings are not updated with
75 #. Browse for the project's General information.
77 #. Click on the ssh tab.
79 #. Clone desired repo. For example:
83 git clone ssh://USERNAME@gerrit.linuxfoundation.org:29418/releng/docs
87 Since we are constantly working on uploading new code into the
88 repositories, we recommend to use SSH clones since the remotes for
89 pushing code get configured appropriately.
94 Recommended if the intention is to view code and not make any contributions:
96 #. Browse the project and click ``General``
98 #. Click ``anonymous http`` tab.
100 #. Clone desired repo. For example:
104 git clone https://gerrit.linuxfoundation.org/releng/docs
106 Authenticated HTTP Clone
107 ------------------------
109 This works everywhere, even behind a proxy or a firewall.
111 #. Get the password by clicking on the username on the top right->Settings->
112 HTTP Password->Generate Password
114 #. Browse for the project and click ``General``.
116 #. Click ``http`` tab.
118 #. Clone desired repo. For example:
122 git clone https://USERNAME@gerrit.linuxfoundation.org/infra/a/releng/docs
124 #. Follow the user/password prompts.
128 For Gerrit < 2.14 the HTTP password is not the same as the Linux Foundation ID password.
132 For Gerrit with HTTP configuration, the HTTP Password is in the User Name
133 (Top right corner) -> Settings -> HTTP Password -> Generate Password.
135 Clone with commit-msg hook
136 --------------------------
138 Both SSH and HTTP clone options have a clone with commit-msg hook which adds
139 a hook to handle the Change-Id_ field in the footer of the
142 #. Browse for the project and click ``General``.
144 #. Click ``Clone with commit-msg hook``. For example:
146 .. literalinclude:: _static/commit-hook.example
151 .. literalinclude:: _static/commit-hook-curl.example
156 The hook implementation is intelligent at inserting the Change-Id_ line before
157 any Signed-off-by or Acked-by lines placed at the end of the commit message by
158 the author, but if no lines are present then it will insert a blank line, and
159 add the Change-Id_ at the bottom of the message.
161 If a Change-Id_ line is already present in the message footer, the script will do
162 nothing, leaving the existing Change-Id_ unmodified. This permits amending an existing
163 commit, or allows the user to insert the Change-Id_ manually after copying it from
164 an existing change viewed on the web.
166 #. (Optional). To prevent the Change-Id_ addition, set gerrit.createChangeId to false in the
169 Push patches to Gerrit
170 ======================
172 #. Open a shell to the directory containing the project repo
173 #. Create a local working branch, based on the branch you would like to make
179 git checkout -b new_feature_branch origin/master
181 Replace *origin/master* with whichever remote/branch you need to contribute
182 to. Typically master is the latest development branch.
184 #. Make the modifications you would like to change in the project
185 #. Stage the modified files for commit. (Repeat for all files modified)
189 git add /path/to/file
191 #. Verify the staged files by running ``git status``
192 #. Commit the staged files by amending the patch
200 The '-s' argument signs the commit message with your name and email and
201 is a statement that you agree to the :ref:`dco`.
203 #. Push the patch to Gerrit using one of the 2 methods documented:
205 #. :ref:`gerrit-push-git-review`
206 #. :ref:`gerrit-push-git-push`
208 .. _gerrit-push-git-review:
210 Push using git review
211 ---------------------
213 We recommend using `git-review <https://docs.openstack.org/infra/git-review/>`_
214 if possible as it makes working with Gerrit much easier.
216 #. Install ``git-review`` via your local package management system
218 If your distro does not package git-review or you need a newer version.
220 Install it via PyPi in a virtualenv_ environment:
224 virtualenv ~/.virtualenvs/git-review
225 pip install git-review
227 #. Push the patch to Gerrit
233 We can optionally pass the parameter ``-t my_topic`` to set a
234 :ref:`topic <gerrit-topics>` in
235 Gerrit. Useful when we have related patches to organize in one
236 :ref:`topic <gerrit-topics>`.
238 Once pushed we should see some output in the terminal as described in
239 :ref:`Gerrit Push Output <gerrit-push-output>`.
241 .. _gerrit-push-git-push:
246 This method is a useful fallback in situations where we cannot use
247 :ref:`git-review <gerrit-push-git-review>`.
249 #. Use the following command:
253 git push <remote> HEAD:refs/for/master
255 Where <remote> is the Gerrit location to push the patch to. Typically
256 'origin' but can also be 'gerrit' depending on how we have our local repo
261 Notice the word "for" is explicitly intending to perform the push into Gerrit.
262 Using "heads" instead, will attempt to make the a push into the repository bypassing
263 Gerrit which can come in handy for some isolated cases (when having force push rights).
264 Another variable commonly used is "refs/changes/<gerrit-number>" which is an explicit
265 way of making an update to an existing gerrit. In such case, is best to let gerrit handle
266 this via Change-Id_ in the commit text.
268 More options for this command: `git-push <https://git-scm.com/docs/git-push>`_.
270 Once pushed we should see some output in the terminal as described in
271 :ref:`Gerrit Push Output <gerrit-push-output>`.
273 .. _gerrit-push-output:
278 After pushing a commit to Gerrit we should see the following output:
280 .. literalinclude:: _static/push-success.example
283 This output includes a URL to the patch. The number at the end is the patch's
286 Update an existing patch
287 ========================
289 In a healthy Open Source project code reviews will happen and we will need to
290 amend the patches until reviewers are happy with the change. This section will
291 walk through the process of updating a patch that is already in
294 #. Open a shell to the directory containing the project repo
295 #. Pull the latest version of the patch from Gerrit
299 git review -d ${change_number}
301 The change number is in the URL of the Gerrit patch.
302 For example if the URL is https://git.opendaylight.org/gerrit/75307
303 then run ``git review -d 75307`` to pull the corresponding changes.
305 (Optional) View information on the latest changes made to that patch.
307 * To view the edited files, run ``git show``.
308 * To view a listing of the edited files and the number of lines in those
309 files, run ``git show --stat``.
311 #. Rebase the patch before you start working on it
317 This is to ensure that the patch incorporates the latest version of the
318 repo and is not out of date.
320 #. Make the necessary changes to the patch with your favorite editor
321 #. Check the state of the repo by running ``git status``
322 #. Stage the modified files for commit. (Repeat for all files modified)
326 git add /path/to/file
328 #. Verify the staged files by running ``git status``
329 #. Commit the staged files by amending the patch
335 #. Update the current patch description and then save the commit request.
337 If you feel as though you added enough work on the patch, add your name
338 in the footer with a line ``Co-Authored-By: Firstname Lastname <email>``.
340 #. Rebase the patch one last time
346 This is to ensure that the patch incorporates the latest version of the
347 repo and is not out of date.
349 #. Submit your files for review:
355 You will receive 2 emails from Gerrit Code Review: the first indicating that
356 a build to incorporate your changes has started; and the second indicating
357 the whether the build passed or failed. Refer to the console logs if the
358 build has failed and amend the patch as necessary.
360 Update a patch with dependent changes
361 =====================================
363 In the case where a patch depends on another in review Gerrit patch, we will
364 need to rebase the commit against the latest patchset of the dependent change
365 in Gerrit. The best way to do this is to retrieve the latest version of the
366 dependent change and then cherry-pick our patch on top of the change.
368 #. Fetch latest parent patch set
372 git review -d <parent-gerrit-id>
374 #. Cherry-pick out patch on top
378 git review -x <patch-gerrit-id>
380 #. Push patch back up to Gerrit
386 Rebasing a change against master
387 ================================
389 In the case that your patchset cannot be re-based via the U/I (merge conflict)
393 git pull origin master
398 git rebase --continue
404 All contributions to Git repositories use Gerrit for code review.
406 The code review process provides constructive feedback about a proposed change.
407 Committers and interested contributors will review the change, give their feedback,
408 propose revisions and work with the change author through iterations of the patch until
409 it’s ready for merging.
411 Managing and providing feedback for the change happens via Gerrit web UI.
413 .. figure:: _static/gerrit-wide-view.png
420 Change authors will want to push changes to Gerrit before they are actually
421 ready for review. This is an encouraged good practice. It has been the
422 experience of experienced community members that pushing often tends to reduce
423 the amount of work and ensures speedy code reviews.
427 This is not required and in some projects, not encouraged, but the general idea
428 of making sure patches are ready for review when submitted is a good one.
432 While in draft state, Gerrit triggers, e.g., verify Jenkins jobs, won’t run
433 by default. You can trigger them despite it being a draft by adding
434 "Jenkins CI" (or the corresponding Jenkins automation account) as a
435 reviewer. You may need to do a recheck by replying with a comment
436 containing ``recheck`` to trigger the jobs after adding the reviewer.
438 To mark an uploaded change as not ready for attention by committers and interested
439 contributors (in order of preference), either mark the Gerrit a draft (by adding
440 a ``-D`` to your ``git review`` command), vote -1 on it yourself or edit the commit
441 message with "WIP" ("Work in Progress").
443 Do not add committers to the Reviewers list for a change while in the pre-review
444 state, as it adds noise to their review queue.
449 Once an author wants a change reviewed, they need to take some actions to put it on
450 the radar of the committers.
452 If the change it's a draft, you'll need to publish it. Do this from the Gerrit web UI.
454 .. figure:: _static/gerrit-publish-button.png
456 Gerrit Web UI button to publish a draft change.
458 Remove your -1 vote if you've marked it with one. If you think the patch is ready for
459 merge, vote +1. If there is not an automated job to test your change and vote +1/-1
460 for Verified, you will need to do as much testing yourself as possible and then manually
461 vote +1 to Verified. You can also vote +1 for Verified if you have done testing in
462 addition to any automated tests. Describing the testing you did or did not do is
465 .. figure:: _static/gerrit-voting-interface.png
467 Gerrit voting interface, exposed by the Reply button.
469 Once the change gets published and you have voted for merging, add the people who
470 need to review/merge the change to the Gerrit Reviewers list. The auto-complete for
471 this Gerrit UI field is somewhat flaky, but typing the full name from the start
474 .. figure:: _static/gerrit-reviewers-interface.png
476 Gerrit Reviewers list with Int/Pack committers added
478 Reviewers will give feedback via Gerrit comments or inline against the diff.
480 .. figure:: _static/gerrit-inline-feedback.png
482 Gerrit inline feedback about a typo
484 Updated versions of the proposed change get pushed as new patchsets to the same
485 Gerrit, either by the original submitter or other contributors. Amending proposed changes
486 owned by others while reviewing may be more efficient than documenting the problem, -1ing,
487 waiting for the original submitter to make the changes, re-reviewing and merging.
489 Download changes for local manipulation and re-uploaded updates via git-review.
491 See `Update an existing patch`_ above. Once you have re-uploaded the patch the Gerrit web
492 UI for the proposed change will reflect the new patchset.
494 .. figure:: _static/gerrit-patch-update-history.png
496 Gerrit history showing a patch update
498 Reviewers will use the diff between the last time they gave review and the current patchset
499 to understand updates, speeding the code review process.
501 .. figure:: _static/gerrit-diff-menu.png
505 Iterative feedback continues until reaching consensus (typically: all active reviewers +1/+2
506 and no -1s nor -2s), at least one committer +2s and a committer merges the change.
508 .. figure:: _static/gerrit-code-review-votes.png
510 Gerrit code review votes
515 Once a patch has gotten a +2 from a committer and they have clicked the submit button the
516 project's merge job should run and publish the project's artifacts to Nexus. Once completed,
517 other projects will be able to see the results of that patch.
519 This is important when merging dependent patches across projects. You will need to wait
520 for the merge job to run on one patch before any patches in other projects depending on
521 it will successful verify.
526 Generating SSH keys for your system
527 -----------------------------------
529 You must have SSH keys for your system to register with your Gerrit
530 account. The method for generating SSH keys is different for different
531 types of operating systems.
533 The key you register with Gerrit must be identical to the one you will
534 use later to pull or edit the code. For example, if you have a
535 development VM which has a different UID login and keygen than that of
536 your laptop, the SSH key you generate for the VM is different from the
537 laptop. If you register the SSH key generated on your VM with Gerrit and
538 do not reuse it on your laptop when using Git on the laptop, the pull
543 Here is more information on `SSH keys for Ubuntu
544 <https://help.ubuntu.com/community/SSH/OpenSSH/Keys>`_
545 and more on `generating SSH keys
546 <https://help.github.com/articles/generating-ssh-keys/>`_
548 For a system running Ubuntu operating system, follow the steps below:
550 #. Run the following command::
556 #. Save the keys, and add a passphrase for the keys.
558 This passphrase protects your private key stored in the hard drive.
559 You must use the passphrase to use the keys every time you need
560 to login to a key-based system::
562 Generating public/private rsa key pair.
563 Enter file in which to save the key (/home/b/.ssh/id_rsa):
564 Enter passphrase (empty for no passphrase):
565 Enter same passphrase again:
567 Your public key is now available as **.ssh/id\_rsa.pub** in your home
570 .. _register-key-gerrit:
572 Register your SSH key with Gerrit
573 ---------------------------------
575 #. Using a Google Chrome or Mozilla Firefox browser, go to
578 #. Click **Sign In** to access the repositories.
580 .. figure:: _static/gerrit-sign-in.png
581 :alt: Sign into Gerrit
585 #. Click your name in the top right corner of the window and then click
588 The **Settings** page.
590 .. figure:: _static/gerrit-settings.png
591 :alt: Settings page for your Gerrit account
593 Settings page for your Gerrit account
595 #. Click **SSH Public Keys** under **Settings**.
597 #. Click **Add Key**.
599 #. In the **Add SSH Public Key** text box, paste the contents of your
600 **id\_rsa.pub** file and then click **Add**.
602 .. figure:: _static/gerrit-ssh-keys.png
603 :alt: Adding your SSH key
607 To verify your SSH key, try using an SSH client to connect to Gerrit’s
610 $ ssh -p 29418 <sshusername>@gerrit.<project>.org
611 Enter passphrase for key '/home/cisco/.ssh/id_rsa':
612 **** Welcome to Gerrit Code Review ****
615 Submit a patch over HTTPS
616 =========================
618 While we recommend you submit patchsets over SSH some users may need to
619 submit patchsets over HTTPS due to corporate network policies such as
620 the blocking of high range ports or outgoing SSH.
622 To submit code to Gerrit over HTTPS follow these steps.
626 This guide uses the Linux Foundation Gerrit server and the
627 releng/docs project as an example. Differences may vary with other
630 Configure your Machine
631 ----------------------
633 #. Generate a HTTPS password
637 Required when uploading patches to Gerrit servers via HTTPS.
639 Navigate to `<https://gerrit.linuxfoundation.org/infra/#/settings/http-password>`_
640 and click **Generate Password**. Write this to the file **.netrc** in your
641 home directory excluding the angle brackets::
643 machine gerrit.linuxfoundation.org user <username> password <http-password>
645 #. Clone the repository over HTTPS using your Linux Foundation ID
647 .. code-block:: shell
649 git clone https://bramwelt@gerrit.linuxfoundation.org/infra/releng/docs
651 #. Download the commit-msg git hook
653 .. code-block:: shell
655 curl -Lo .git/hooks/commit-msg \
656 https://gerrit.linuxfoundation.org/infra/tools/hooks/commit-msg && \
657 chmod +x .git/hooks/commit-msg
659 Due to a bug in git-review, you need to download the commit-msg hook
660 manually to the .git/hooks/ directory or ``git-review -s`` will fail.
662 Configure the Repository
663 ------------------------
665 Because ``git-review`` attempts to use SSH by default, you need
666 configure the git-review scheme and port through git-config in the
671 The Gerrit context path on the Linux Foundation Gerrit server is
672 ``infra/``. Others Gerrit servers may use ``gerrit/`` or ``r/``.
674 #. Perform the following commands
676 .. code-block:: shell
679 git config gitreview.scheme https
680 git config gitreview.port 443
681 git config gitreview.project infra/releng/docs
683 #. Verify the configuration by running the following command::
687 If successful, the command will not print anything to the console, and
688 you will be able to submit code with::
692 Otherwise ``git-review`` will still request your Gerrit username,
693 indicating a configuration issue.
695 You can check the configuration using verbose output::
702 1. Generate your GPG key.
704 The following instructions work on a Mac, but the general approach
705 should be the same on other OSes.
707 .. literalinclude:: _static/gpg-setup.example
709 If you are collaborating in keysigning, then send the output of
710 ``gpg2 --fingerprint $KEY_ID`` to your coworkers.
714 gpg2 --fingerprint $KEY_ID
715 # in the above example, the $KEY_ID would be F566C9B1
716 # in my case, the output was:
717 # pub 4096R/F566C9B1 2015-04-06 [expires: 2017-04-05]
718 # Key fingerprint = 7C37 02AC D651 1FA7 9209 48D3 5DD5 0C4B F566 C9B1
719 # uid [ultimate] Colin Dixon <colin at colindixon.com>
720 # sub 4096R/DC1497E1 2015-04-06 [expires: 2017-04-05]
722 2. Install gpg, instead of or addition to gpg2.
724 .. note:: you can tell Git to use gpg by doing:
725 ``git config --global gpg.program gpg2``
726 but that then will seem to struggle asking for your
727 passphrase unless you have your gpg-agent set up right.
729 3. Add your GPG to Gerrit
731 a. Run the following at the CLI:
735 gpg --export -a $FINGER_PRINT
736 # e.g., gpg --export -a F566C9B1
737 # in my case the output looked like:
738 # -----BEGIN PGP PUBLIC KEY BLOCK-----
741 # mQINBFUisGABEAC/DkcjNUhxQkRLdfbfdlq9NlfDusWri0cXLVz4YN1cTUTF5HiW
743 # gJT+FwDvCGgaE+JGlmXgjv0WSd4f9cNXkgYqfb6mpji0F3TF2HXXiVPqbwJ1V3I2
746 # -----END PGP PUBLIC KEY BLOCK-----
748 b. Browse to https://git.opendaylight.org/gerrit/#/settings/gpg-keys
750 d. Copy the output from the above command, paste it into the box,
753 4. Set up your Git to sign commits and push signatures
757 git config commit.gpgsign true
758 git config push.gpgsign true
759 git config user.signingkey $FINGER_PRINT
760 # e.g., git config user.signingkey F566C9B1
764 We can create a signed commit with ``git commit -S`` and
765 a signed push with ``git push --signed`` on the CLI instead of
766 configuring it in config if we want to manually control which commits
769 5. Create a signed commit
772 b. Create a signed commit with ``git commit -asm "test commit"``
774 This will result in Git asking you for your passphrase.
777 6. Push to Gerrit with a signed-push with ``git review``
779 This will result in Git asking you for your passphrase.
784 The signing a commit or pushing again with a signed push is not
785 recognized as a "change" by Gerrit, so if you forget to do either, you
786 need to change something about the commit to get Gerrit to accept the
787 patch again. Slightly tweaking the commit message is a good way.
791 This assumes you have git review set up and push.gpgsign
792 set to true. Otherwise:
794 ``git push --signed gerrit HEAD:refs/for/master``
796 This assumes the gerrit remote is available, if not, configure
797 something like: ``ssh://ckd@git.opendaylight.org:29418/<repo>.git``
798 where repo is something like docs or controller
800 6. Verify the signature
802 To do this, navigate to Gerrit and check for a green check next to your name in the patch.
804 .. figure:: _static/gerrit-signed-push.png
806 Example signed push to Gerrit.
811 Developer's Certificate of Origin (DCO)
812 ---------------------------------------
814 Code contributions to Linux Foundation projects must have a sign-off by the
815 author of the code which indicates that they have read and agree to the DCO.
817 .. literalinclude:: _static/dco-1.1.txt
819 :caption: Developer's Certificate of Origin
822 Refer to https://developercertificate.org/ for original text.
829 Topics are useful as a search criteria in Gerrit. By entering ``topic:foo``
830 as a search criteria we can track related commits. Use one of the following
831 methods to configure topics:
833 1. Directly in the Gerrit UI via the Edit Topic button
834 2. Via ``git review`` using the ``-t topic`` parameter
838 git-review defaults to the local branch name as the topic if it does not
839 match the upstream branch.
841 3. Via ``git push`` using one of the following methods:
845 git push origin HEAD:refs/for/master%topic=some-topic
846 git push origin HEAD:refs/for/master -o topic=some-topic
848 Both methods achieve the same result so is up to preference. Further
849 documentation available at `Gerrit Topics
850 <https://gerrit-review.googlesource.com/Documentation/intro-user.html#topics>`_.
853 .. _Change-Id: https://gerrit.linuxfoundation.org/infra/Documentation/user-changeid.html
854 .. _virtualenv: https://virtualenv.pypa.io/en/stable/