You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 22 Next »

Gerrit is primarily a code inspection tool, but can also be used to track the status of patch as it is build tested, and finally merged to a branch. Developers submit patches to Gerrit using git, and there is a rich browser interface for performing inspections. Inspectors can also pull the change directly to their own repository and inspect the change locally.

To upload changes to Gerrit, you must first register and add an ssh key to your account. For details on setting up your Gerrit account and sending patches, please see the Gerrit documentation.

Gerrit can host many git repositories, and of course each of those repositories can contain many branches. For instance, these are some of the repositories on Gerrit today:

repo

description

status

fs/lustre-release

Whamcloud's Lustre for new releases

Gatekeeping in effect

 

branch: b1_8

for 1.8.6+ releases

 

branch: master

for 2.1.0+ releases

fs/lustre-dev

A collection of development branches for Whamcloud developers

no gatekeeping

tools/e2fsprogs

Mirror of kernel.org e2fsprogs, contains lustre branches

limited checkins

 

branch: master-lustre

for 1.41.90+ releases

Managing Changes in Git

Whole books could be written about this topic, and there plenty of online tutorials on the web that explain this in more detail and suggest other methods of managing changes. However, this distilled version is (hopefully) enough to get started.

Typically in git, one creates a new local branch for each change being made. The branch is created based on one of the local, pristine branches follow the main development branches, such as b1_8 or master. A new local branch is usually create using checkout:

$ git checkout -b my-brilliant-idea master

This creates a new branch based on master called my-brilliant-idea, and also makes it the current branch.

In order ensure that the commit description contains the correct name and email address for you, it is possible to specify this directly to Git creating or modifying the .gitconfig file in your home directory.

[user]
        name = Random J. Developer
        email = random@developer.example.org

Now all git commits will use this name/email regardless of which repository the changes are being made in. If you want to specify a different name or email for a specific repository, it is possible to add the same information to the .git/config file in that specific repository.

Once you've made the change, and you're ready to create an inspection, you commit. Before you commit in git, you need to identify which files you want to commit using the "git add" command. If you haven't added any new files, and you want to commit all the files that you have changed (which is the usual case), then you can use the "-a" option to commit:

$ git commit -av

This will put you into an editor to update your commit comment, and when you save it will commit the change locally. The -v option appends the diff to the edit buffer so you can review what is about to be committed. This is very handy.

It is best to commit relatively frequently to keep your changes limited to a single fix. If you notice other, unrelated, issues that need to be fixed, then it's best to put them in a different commit, and on a different branch so they can be submitted to Gerrit separately for inspection, testing, and landing. The stash command is handy for this:

# While fixing a bug you notice something evil that must be fixed.
# First set your current work aside:
$ git stash

# Next go create a new branch and purge the ugliness you just discovered:
$ git create -b my-eyes-are-bleeding master
$ git commit -av

# Now go back to what you were working on:
$ git checkout my-brilliant-idea
$ git stash pop
Formatting Git Commit Comments

See Commit Comments for a detailed description of the commit comment style. If your comments are do not include the Change-Id: line as described below, the patch will be rejected at submission time.

Sample Commit message:

LU-000 component: short description of change under 64 columns

A more detailed explanation of the change being made.  This can be
as detailed as you'd like, possibly several paragraphs in length.

Please provide a detailed explanation of what problem was solved,
a good high-level description of how it was solved, and which
parts of the code were affected (including function names as
needed, for easier searching).  Wrap lines at 72 columns or less.

Signed-off-by: Random J Developer <random@developer.example.org>
Change-Id: Ica9ed1612eab0c4673dee088f8b441d806c64932
Adding the Change-Id field

Gerrit will automatically identify updates to existing patches and update the existing request instead of creating a new one. This preserves the history of patch comments, and allows comparing old and new versions of a patch for more efficient inspections. For this to work properly the changes you create locally need to have a unique commit id in them. To get the Commit-Id: field inserted automatically, copy the commit-msg hook from the build/ subdirectory into each Git repository's .git/hooks/ directory. This will update the commit message for changes you commit to your repository before they are submitted to Gerrit. The commit-msg hook will also verify that the commit message format matches the format specified above. Similarly, copying the prepare-commit-msg script from build/ to .git/hooks/ will run the build/checkpatch.pl script against each patch at commit time to check it against the Lustre Coding Guidelines.

For older Lustre versions that are missing the commit hooks, they can be copied from a newer branch of Lustre (e.g. master), and the .git/hooks/ directory is shared among all branches (it is not updated when checking out a new branch).

Creating Inspection Requests

An inspection request is created by pushing a change to a special branch on the Gerrit repository. For example, to create a request for a change against master on the main lustre repository, you do this your current working branch on your local branch for inspection:

git push ssh://USER@review.whamcloud.com:29418/fs/lustre-release HEAD:refs/for/master

for the "master" branch of the lustre-release repo, or:

git push ssh://USER@review.whamcloud.com:29418/fs/lustre-release HEAD:refs/for/b1_8

for the "b1_8" branch of the lustre-release repo, or:

git push ssh://USER@review.whamcloud.com:29418/tools/e2fsprogs HEAD:refs/for/master-lustre

for the "master-lustre" branch of the e2fsprogs repo.

For convenience, you can add this to your ~/.ssh/config file:

Host review
  Hostname review.whamcloud.com
  Port 29418
  User \{YourUserid\}
  IdentityFile ~/.ssh/my-key-id_rsa

Creating an inspection request for a change against master (assuming the remote alias has been added to ssh config):

git push ssh://review/fs/lustre-release HEAD:refs/for/master

Creating an inspection request for a change against b1_8 (assuming the remote alias has been added to ssh config):

git push ssh://review/fs/lustre-release HEAD:refs/for/b1_8

And add a the Gerrit server as a remote to your git repository:

$ git remote add review ssh://review/fs/lustre-release
Pushing a Git Tag

Switch to the branch you want to create a branch in (normally master or b1_8).

Create the tag with:

git tag -a TAG_NAME

then push it upstream with

git push TAG_NAME

Note, this requires certain privileges on the server. If review is a secondary server for your repository, use

git push review TAG_NAME
Updating Inspection Requests

Gerrit makes it easy to update an inspection request with a new patch, and doing this allows inspectors to see differences between the patches so they only need to inspect the changes. Also, the original inline comments are maintained and moved to the new patches. The key to keeping updated inspection requests linked to the original patch is the Change-Id: field - this is what Gerrit uses to find the original patch to update.

A critical thing to point out is that you need submit a new version of the entire change - not just an update to the change. The usual way of doing this is to apply the updates to your tree as usual and create a new commit (this time the commit message doesn't matter as you are about to change it). Then, merge the two changes using git rebase -i <parent-branch>. Interactive rebase will display a list of patches in an editor, and you can "squash" the the modifications to the patch in the new commit into the original patch. (See the help text in the commit message editor window for more information.) Then it will put you in an editor again to manually merge the two commit messages. Make sure you keep the original Change-Id: line, and delete the new one, and edit the commit messages so they're combined into a single commit. If you don't have a Change-Id: line in your commit message (because you didn't install the commit-msg hook above, do that now) you can copy it from the top Gerrit web page for that change and paste it into the new commit message. Once the change is committed, push your branch to Gerrit again, and the original request will be updated with the new version of the patch.

The easiest way to update the most recent commit (which is often the one you want to update), is to use git commit --amend -a.

  • No labels