Jump to: navigation, search

Difference between revisions of "Gerrit Workflow"

Line 4: Line 4:
 
'''Note'''
 
'''Note'''
  
This workflow for developers is a work in progress and is not ready
+
This workflow for developers is a work in progress and is only in use
for use by OpenStack projects. Please see [[LifeWithBzrAndLaunchpad]]
+
for the Glance and Keystone projects.
for current project practices.
+
 
 +
Please see [[LifeWithBzrAndLaunchpad]] for other current project
 +
practices.
  
 
</nowiki></pre>
 
</nowiki></pre>
Line 21: Line 23:
 
to understand the workflow in use, and then consult this section when
 
to understand the workflow in use, and then consult this section when
 
you need to start work on a new [[OpenStack]] project.
 
you need to start work on a new [[OpenStack]] project.
 +
 +
Before setting up your first project, add a global git alias to make
 +
reviewing easier (you only have to do this once, not for each
 +
project):
 +
 +
 +
<pre><nowiki>
 +
cat <<EOF >>~/.gitconfig
 +
[alias]
 +
review = !sh `git rev-parse --show-toplevel`/tools/rfc.sh
 +
EOF
 +
</nowiki></pre>
 +
  
 
If you are going to contribute code to a project, run the following
 
If you are going to contribute code to a project, run the following
Line 43: Line 58:
 
git clone git://github.com/openstack/$PROJECT.git
 
git clone git://github.com/openstack/$PROJECT.git
  
# Install the Change-Id commit message hook:
+
# Set up the Gerrit Change-Id hook, and remote repository:
 
cd $PROJECT
 
cd $PROJECT
scp -p -P 29418 $USERNAME@review.openstack.org:hooks/commit-msg .git/hooks/
+
git review
 +
</nowiki></pre>
  
# Add Gerrit as a remote repository:
+
 
git remote add gerrit ssh://$USERNAME@review.openstack.org:29418/openstack/$PROJECT.git
+
The command '''git review''' calls the global git alias you set up
 +
earlier.  It invokes the script "tools/rfc.sh" which we maintain in
 +
each [[OpenStack]] repository.  It makes sure that the Gerrit Change-Id
 +
hook is installed, the gerrit remote repository is configured, your
 +
changes are based on the tip of the master repository, and submits
 +
your changes with an appropriate topic.
 +
 
 +
For more information about how to use gerrit, please continue reading.
 +
 
 +
== Normal Workflow ==
 +
 
 +
Once your local repository is set up as above, you must use the
 +
following workflow.
 +
 
 +
Make sure you have the latest upstream changes:
 +
 
 +
<pre><nowiki>
 +
git checkout master
 +
git pull origin master
 
</nowiki></pre>
 
</nowiki></pre>
  
  
If this is the first project you have set up with Gerrit, you should
+
Create a [http://progit.org/book/ch3-4.html topic branch] to hold
add a global git alias to make reviewing easier (you only have to do
+
your work and switch to it.  If you are working on a blueprint, name
this once, not for each project):
+
your topic branch '''bp/BLUEPRINT''' where BLUEPRINT is the name of a
 +
blueprint in launchpad (e.g., "bp/authentication").  Otherwise, give
 +
it a meaningful name because it will show up as the topic for your
 +
change in Gerrit.
  
  
 
<pre><nowiki>
 
<pre><nowiki>
cat <<EOF >>~/.gitconfig
+
git checkout -b TOPIC-BRANCH
[alias]
 
        review = push gerrit HEAD:refs/for/master
 
EOF
 
 
</nowiki></pre>
 
</nowiki></pre>
  
  
For more information about how to use gerrit, please continue reading.
+
=== Committing Changes ===
  
== Normal Workflow ==
+
Git commit messages should start with a short 50 character or less
 +
summary in a single paragraph.  The following paragraph(s) should
 +
explain the change in more detail.
  
Once your local repository is set up as above, you must use the following workflow.
+
If your changes addresses a blueprint or a bug, be sure to mention
 +
them in the commit message using the following syntax:
  
Make sure you have the latest upstream changes:
 
  
 
<pre><nowiki>
 
<pre><nowiki>
git checkout master
+
blueprint BLUEPRINT
git pull origin master
+
bug #######
 
</nowiki></pre>
 
</nowiki></pre>
  
  
Create a [http://progit.org/book/ch3-4.html topic branch] to hold your work and switch to it:
+
e.g.:
  
  
 
<pre><nowiki>
 
<pre><nowiki>
git checkout -b TOPIC-BRANCH
+
Adds keystone support.
 +
 
 +
Implements blueprint authentication.  Fixes bug 123456.
 +
 
 +
(Long description of the change).
 
</nowiki></pre>
 
</nowiki></pre>
  
Line 100: Line 140:
 
'''Note'''
 
'''Note'''
  
Do not check in changes on your master branch.  Doing so will cause merge commits when you pull new upstream changes, and merge commits will not be accepted by Gerrit.
+
Do not check in changes on your master branch.  Doing so will cause
 +
merge commits when you pull new upstream changes, and merge commits
 +
will not be accepted by Gerrit.
 
</nowiki></pre>
 
</nowiki></pre>
  
Line 106: Line 148:
 
=== Long-lived Topic Branches ===
 
=== Long-lived Topic Branches ===
  
If you are working on a larger project, you may be working on your topic branch for a while.  In that case, you may want to check in your changes frequently during development and you will need to rebase your change to the current state of the master repository before submitting it for code review.  In these situations you should prepare your change carefully before submitting it.
+
If you are working on a larger project, you may be working on your
 +
topic branch for a while.  In that case, you may want to check in your
 +
changes frequently during development and you will need to rebase your
 +
change to the current state of the master repository before submitting
 +
it for code review.  In these situations you should prepare your
 +
change carefully before submitting it.
  
If the master repository has changed since you started, you should rebase your changes to the current state.  And if you have made many small commits, you should squash them so that they do not show up in the public repository.  Remember: each commit will become a change in Gerrit, and need to be approved separately.  If you are making one "change" to the project, squash your many "checkpoint" commits into one commit for public consumption.  Here's how to do both of those:
+
If the master repository has changed since you started, you should
 +
rebase your changes to the current state.  And if you have made many
 +
small commits, you should squash them so that they do not show up in
 +
the public repository.  Remember: each commit will become a change in
 +
Gerrit, and need to be approved separately.  If you are making one
 +
"change" to the project, squash your many "checkpoint" commits into
 +
one commit for public consumption.  Here's how to do both of those:
  
  
Line 119: Line 172:
  
  
Use the editor to squash any commits that should not appear in the public history.  If you want one change to be submitted to Gerrit, you should only have one "pick" line at the end of this process.  After completing this, you will be able to prepare your public commit message(s) in your editor.  You will start with the commit message from the commit that you picked, and it should have a Change-Id line in the message.  Be sure to leave that Change-Id line in place when editing.
+
Use the editor to squash any commits that should not appear in the
 +
public history.  If you want one change to be submitted to Gerrit, you
 +
should only have one "pick" line at the end of this process.  After
 +
completing this, you will be able to prepare your public commit
 +
message(s) in your editor.  You will start with the commit message
 +
from the commit that you picked, and it should have a Change-Id line
 +
in the message.  Be sure to leave that Change-Id line in place when
 +
editing.
  
Once the commit history in your branch looks correct, run '''git review''' to submit your changes to Gerrit.
+
Once the commit history in your branch looks correct, run '''git
 +
review''' to submit your changes to Gerrit.
  
 
=== Updating a Change ===
 
=== Updating a Change ===
Line 137: Line 198:
  
  
= Gerrit, Jenkins, and [[GitHub]] Workflow =
+
= Gerrit, Jenkins, and [[GitHub]] =
  
 
[https://github.com/ GitHub] is a resource for managing Git
 
[https://github.com/ GitHub] is a resource for managing Git
Line 161: Line 222:
 
== Using Gerrit ==
 
== Using Gerrit ==
  
The next sections will describe what steps a developer should take to
+
The next sections describe how Gerrit fits into the developer
use Gerrit as part of this workflow.
+
workflow.
  
 
=== Gerrit Accounts ===
 
=== Gerrit Accounts ===
Line 168: Line 229:
 
Visit https://review.openstack.org/ and click the '''Sign In''' link
 
Visit https://review.openstack.org/ and click the '''Sign In''' link
 
at the top-right corner of the page.  Log in with your Launchpad ID.
 
at the top-right corner of the page.  Log in with your Launchpad ID.
 
 
<pre><nowiki>#!wiki caution
 
'''Note'''
 
 
The OpenStack Gerrit site currently uses a self-signed SSL
 
certificate; this will be replaced with a certificate from a
 
recognized CA soon.
 
</nowiki></pre>
 
 
  
 
Because Gerrit uses Launchpad OpenID single sign-on, you won't need a
 
Because Gerrit uses Launchpad OpenID single sign-on, you won't need a
Line 194: Line 245:
 
and SSH keys.  If your group membership is not correct, please email
 
and SSH keys.  If your group membership is not correct, please email
 
openstack-ci-admins@lists.launchpad.net.
 
openstack-ci-admins@lists.launchpad.net.
 
 
<pre><nowiki>#!wiki caution
 
'''Note'''
 
 
For each project you contribute to, you will want to make Gerrit
 
notify you of changes to the project's master repo. To do so, you will
 
want to go to https://review.openstack.org/#settings,projects and
 
enter the names of projects to watch.
 
 
</nowiki></pre>
 
 
 
=== Cloning a Git Repository ===
 
 
Clone a copy of the repository for the [[OpenStack]] project you want to
 
work on from [[GitHub]] using a command similar to the following:
 
 
 
<pre><nowiki>
 
git clone git://github.com/openstack/$PROJECT.git
 
</nowiki></pre>
 
 
 
Or if you have a [[GitHub]] account, via SSH:
 
 
 
<pre><nowiki>
 
git clone git@github.com:openstack/$PROJECT.git
 
</nowiki></pre>
 
 
 
Where ''$PROJECT'' is the name of the project you want to work on.  The
 
correct path to use can also be found on the project's page on [[GitHub]].
 
  
 
=== Setting up Git for Use with Gerrit ===
 
=== Setting up Git for Use with Gerrit ===
Line 244: Line 261:
 
is even sent to Gerrit.
 
is even sent to Gerrit.
  
Use the command below to add a commit hook to your local Git
+
The rfc.sh script (or "git review") installs a commit hook into your
repository that automatically adds Change-Id lines to your commits:
+
repository that automatically adds Change-Id lines to your commits..
 
 
 
 
<pre><nowiki>
 
scp -p -P 29418 $USERNAME@review.openstack.org:hooks/commit-msg .git/hooks/
 
</nowiki></pre>
 
 
 
 
 
Where ''$USERNAME'' is your Gerrit/Launchpad username.
 
  
 
The Gerrit manual goes into more detail about [https://review.openstack.org/Documentation/user-changeid.html change IDs].
 
The Gerrit manual goes into more detail about [https://review.openstack.org/Documentation/user-changeid.html change IDs].
Line 259: Line 268:
 
==== Pushing Changes from Git ====
 
==== Pushing Changes from Git ====
  
To make pushing proposed changes to Gerrit easier, you should register
+
Simply running '''git review''' should be sufficient to push your
Gerrit as a remote repository tracked by Git.  Run the following
+
changes to Gerrit, assuming your repository is set up as described
command inside your local Git repository:
+
above, you don't need to read the rest of this section unless you want
 
+
to use an alternate workflow.
 
 
<pre><nowiki>
 
git remote add gerrit ssh://$USERNAME@review.openstack.org:29418/openstack/$PROJECT.git
 
</nowiki></pre>
 
 
 
 
 
Where ''$USERNAME'' is the username you registered with Gerrit and
 
''$PROJECT'' is the name of the current project.  Then when you are
 
ready to push a change to Gerrit for review, you may issue a command
 
like:
 
 
 
 
 
<pre><nowiki>
 
git push gerrit HEAD:refs/for/master
 
</nowiki></pre>
 
 
 
  
To make pushing changes for review even easier, you should add a git
+
If you want to push your changes without using rfc.sh, you can push
alias.  This is a global change which you only need to do once.  Edit
+
changes to gerrit like you would any other git repository, using the
your '''~/.gitconfig''' file and add an alias like this:
+
following syntax (assuming "gerrit" is configured as a remote
 +
repository):
  
  
 
<pre><nowiki>
 
<pre><nowiki>
[alias]
+
git push gerrit HEAD:refs/for/$BRANCH[/$TOPIC]
        review = push gerrit HEAD:refs/for/master
 
 
</nowiki></pre>
 
</nowiki></pre>
  
  
From then on, pushing a change to gerrit is as simple as:
+
Where $BRANCH is the name of the Gerrit branch to push to (usually
 
+
"master"), and you may optionally specify a Gerrit topic by appending
 
+
it after a slash character.
<pre><nowiki>
 
git review
 
</nowiki></pre>
 
 
 
  
 
==== Git SSH Commands ====
 
==== Git SSH Commands ====

Revision as of 00:58, 19 August 2011


#!wiki caution
'''Note'''

This workflow for developers is a work in progress and is only in use
for the Glance and Keystone projects.

Please see [[LifeWithBzrAndLaunchpad]] for other current project
practices.


<<TableOfContents()>>

Quick Reference

Project Setup

This section is intended as a quick reference of commands needed to begin work in a new repository. Please read this entire documentation to understand the workflow in use, and then consult this section when you need to start work on a new OpenStack project.

Before setting up your first project, add a global git alias to make reviewing easier (you only have to do this once, not for each project):


cat <<EOF >>~/.gitconfig
[alias]
	review = !sh `git rev-parse --show-toplevel`/tools/rfc.sh
EOF


If you are going to contribute code to a project, run the following commands for each project you intend to work with.

First, set these variables to the name of the project and your own username on Launchpad:


PROJECT=keystone
USERNAME=jsmith


Then run the following commands to clone the repository and configure it for use with Gerrit:


# Clone the repository
git clone git://github.com/openstack/$PROJECT.git

# Set up the Gerrit Change-Id hook, and remote repository:
cd $PROJECT
git review


The command git review calls the global git alias you set up earlier. It invokes the script "tools/rfc.sh" which we maintain in each OpenStack repository. It makes sure that the Gerrit Change-Id hook is installed, the gerrit remote repository is configured, your changes are based on the tip of the master repository, and submits your changes with an appropriate topic.

For more information about how to use gerrit, please continue reading.

Normal Workflow

Once your local repository is set up as above, you must use the following workflow.

Make sure you have the latest upstream changes:

git checkout master
git pull origin master


Create a topic branch to hold your work and switch to it. If you are working on a blueprint, name your topic branch bp/BLUEPRINT where BLUEPRINT is the name of a blueprint in launchpad (e.g., "bp/authentication"). Otherwise, give it a meaningful name because it will show up as the topic for your change in Gerrit.


git checkout -b TOPIC-BRANCH


Committing Changes

Git commit messages should start with a short 50 character or less summary in a single paragraph. The following paragraph(s) should explain the change in more detail.

If your changes addresses a blueprint or a bug, be sure to mention them in the commit message using the following syntax:


blueprint BLUEPRINT
bug #######


e.g.:


Adds keystone support.

Implements blueprint authentication.  Fixes bug 123456.

(Long description of the change).


Make your changes, commit them, and submit them for review:


git commit -a
git review


#!wiki caution
'''Note'''

Do not check in changes on your master branch.  Doing so will cause
merge commits when you pull new upstream changes, and merge commits
will not be accepted by Gerrit.


Long-lived Topic Branches

If you are working on a larger project, you may be working on your topic branch for a while. In that case, you may want to check in your changes frequently during development and you will need to rebase your change to the current state of the master repository before submitting it for code review. In these situations you should prepare your change carefully before submitting it.

If the master repository has changed since you started, you should rebase your changes to the current state. And if you have made many small commits, you should squash them so that they do not show up in the public repository. Remember: each commit will become a change in Gerrit, and need to be approved separately. If you are making one "change" to the project, squash your many "checkpoint" commits into one commit for public consumption. Here's how to do both of those:


git checkout master
git pull origin master
git checkout TOPIC-BRANCH
git rebase -i master


Use the editor to squash any commits that should not appear in the public history. If you want one change to be submitted to Gerrit, you should only have one "pick" line at the end of this process. After completing this, you will be able to prepare your public commit message(s) in your editor. You will start with the commit message from the commit that you picked, and it should have a Change-Id line in the message. Be sure to leave that Change-Id line in place when editing.

Once the commit history in your branch looks correct, run git review to submit your changes to Gerrit.

Updating a Change

If the code review process suggests additional changes, make them and ammend the existing commit. Leave the existing Change-Id: footer in the commit message as-is and Gerrit will know that this is an updated patch for an existing change:


git commit -a --amend 
git review


Gerrit, Jenkins, and GitHub

GitHub is a resource for managing Git code repositories and interacting with other developers. Jenkins is used to continuously test all of the components of OpenStack to ensure functionality and to verify that each change to the code base works as intended. Gerrit is a code review system originally developed for use by the Android Open Source Project and allows us to build a workflow where every change is peer-reviewed and tested by Jenkins before being merged into the main repository.

After making a change in their local Git repository, developers can easily push that change to Gerrit as a proposed change for the project. Jenkins will automatically run functional tests on the code and provide feedback on the change in Gerrit. Any OpenStack developer can provide feedback (in the form of a comment, or even line-by-line annotations) using Gerrit, and the core developers of the project can indicate whether they approve of the patch as is, or would like to see changes before it is integrated. Once patches are merged by Gerrit, the repository is pushed to the canonical public repository on GitHub.

Using Gerrit

The next sections describe how Gerrit fits into the developer workflow.

Gerrit Accounts

Visit https://review.openstack.org/ and click the Sign In link at the top-right corner of the page. Log in with your Launchpad ID.

Because Gerrit uses Launchpad OpenID single sign-on, you won't need a separate password for Gerrit, and once you log in to one of Launchpad, Gerrit, or Jenkins, you won't have to enter your password for the others.

Gerrit accounts are automatically synchronized with Launchpad, so your Gerrit account should already have the same username, full name, email address, ssh keys, and group membership.

Some information in Launchpad is not publicly available and so may not be copied over. The first time you log into Gerrit, you should click the Settings link at the top of the page, and then make sure that your Contact Information, SSH Public Keys, and Groups look correct. If not, please register your email address and SSH keys. If your group membership is not correct, please email openstack-ci-admins@lists.launchpad.net.

Setting up Git for Use with Gerrit

For a more comprehensive look at using Gerrit, see the Gerrit manual.

Change-Id Hook

Gerrit uses a Change-Id footer in commits so that it can link Git commits to changes stored in its database. When you upload a revised change (to correct a problem or respond to code review comments), Gerrit will use the Change-Id footer to attach the commit as a new patchset on the existing gerrit change. This works best if the Change-Id is already in the original commit message, before it is even sent to Gerrit.

The rfc.sh script (or "git review") installs a commit hook into your repository that automatically adds Change-Id lines to your commits..

The Gerrit manual goes into more detail about change IDs.

Pushing Changes from Git

Simply running git review should be sufficient to push your changes to Gerrit, assuming your repository is set up as described above, you don't need to read the rest of this section unless you want to use an alternate workflow.

If you want to push your changes without using rfc.sh, you can push changes to gerrit like you would any other git repository, using the following syntax (assuming "gerrit" is configured as a remote repository):


git push gerrit HEAD:refs/for/$BRANCH[/$TOPIC]


Where $BRANCH is the name of the Gerrit branch to push to (usually "master"), and you may optionally specify a Gerrit topic by appending it after a slash character.

Git SSH Commands

If you find you are frequently executing Gerrit commands via SSH, you may wish to add something like the following to your ~/.ssh/config file:


Host review
  Hostname review.openstack.org
  Port 29418
  User USERNAME


Which may shorten some SSH commands; the following are equivalent:


ssh -p 29418 review.openstack.org gerrit ls-projects
ssh review gerrit ls-projects


Reviewing a Change

Log in to https://review.openstack.org/ to see proposed changes, and review them.

To provide a review for a proposed change in the Gerrit UI, click on the Review button (it will be next to the buttons that will provide unified or side-by-side diffs in the browser). In the code review, you can add a message, as well as a vote (+1,0,-1).

Any Openstack developer may propose or comment on a change (including voting +/-1 on it). Members of the core project team may mark changes as approved (by voting +2).

Once a review is voted up to +2 (two reviewers, or one core-team reviewer voting +2), Jenkins will run the proposed change and verify the merge. If Jenkins successfully tests the change, and there are no -2 code review votes, the change will be automatically merged into the repository.

Gerrit Best Practices

If you are working on unrelated changes, you should use a topic branch so that there isn't a dependency between the changes.

When you start working on a new change, make sure you have the current repository head from github.

For more information about uploading changes to gerrit, see the Uploading Changes section of the Gerrit manual.

Gerrit Errors

missing Change-Id in commit message

If you see an error like this:


 ! [remote rejected] HEAD -> refs/for/master (missing Change-Id in commit message)


Make sure that you have the Change-Id hook installed. If you don't, install it now, and the run git commit --amend and re-save your commit message. The hook will then add a Change-Id line.

If you did have the hook installed, there may be a syntax error with the Change-Id line. It must be in the last paragraph of the commit message, and it must be at the beginning of the line. Your commit message should look like this in your editor:


The text of your commit message is here.
    
Change-Id: I5f55e68d1bdb42a0fa6f0b1a5432786d0395da51


squash commits first

If you see this message:

 ! [remote rejected] HEAD -> refs/for/master (squash commits first)


It means that you are trying to update an existing change in Gerrit, but you created two separate commits. Normally to update a change you should ammend an existing commit (see Updating a Change). If you have already made a second commit, you will need squash the last two commits in your tree. To do that, run:


git rebase -i HEAD~2


Your editor should appear with two commits listed, one per line. Change the word "pick" on the second line to "squash", so that it looks like:


pick   xxxxxxx 2nd commit back
squash yyyyyyy head


And save. You should then be able to upload your commit with git review.

Gerrit Merge Problems

Gerrit will fast-forward or merge changes as necessary when they are approved. If a conflict would be created by a merge, gerrit will not merge the change and will record an error message in the comments for the change. In these cases, you may need to rebase or merge the change, or if the repository head has changed significantly, you may need to change the patch.

If you don't already have the patch in your local repository, Gerrit provides commands on the web page for each change indicating how to download that change. You can then use git to correct the problem.

If you encounter other error messages from Gerrit, the Error Messages section of the Gerrit manual may offer some tips.

Resources

See the Gerrit documentation, especially the User Guide, for more information on how to use Gerrit. It is also available within Gerrit by clicking on the Documentation link on the top of the page.

The Mahara Project also uses Git, Gerit, and Jenkins in a similar manner (though with Gitorious instead of GitHub).

A description of many of the elements of the git workflow