ITK/Gerrit/Primer
This primer is to aid the ITK developer community in using Gerrit. Some of the idiosyncrasies of Gerrit take a little work to understand and appreciate, especially if one is new to using the git distributed revision control system.
Gerrit basics
Gerrit is designed to take a single change with a change log and make it publicly available for comments and revisions. Once the change has been sufficiently reviewed and approved, it will be pushed into the official ITK repository. Gerrit addresses the problem of many changes scattered about many git repositories by bringing them into a central place and allowing commenting and changes to become transparent to the rest of the community.
Creating a Gerrit account
In order to register you need to get an OpenID. Be aware that a GMail account automatically gives you an OpenID.
To register with Gerrit, first have your OpenID ready. Then visit http://review.source.kitware.com/. Click the "Register" link in the upper left. If you have a Google or Yahoo account, click on the "Register with a Google account". This will create your account. Otherwise, enter the URL of an OpenID provider.
git / Gerrit workflow
For the sake of this primer, we'll be making a series of small documentation changes to ITK code. The basic workflow from the developer's standpoint is:
- Clone the ITK official repository
- Create a topic branch
- Edit, commit, edit, commit, ad infinitum
- Compress your branch into a single commit
- Push your changes into Gerrit
- Review
- Stage changes into the ITK official repository
These steps will be detailed in the next sections.
Clone the ITK official repository
The instructions for cloning the official repository are here. For the minimalist:
git clone git://itk.org/ITK.git cd ITK
Create a topic branch
git works well to create "micro-branches". Frequently, branches are considered poor practice in centralized revision control systems such as CVS and Subversion. However, in git branches are typically very easy to work with and manipulate. They are required for working with Gerrit, so get used to them.
We'll call our branch GerritPrimer. The branch may be created it two steps:
git branch GerritPrimer # Create a new branch from our existing revision git checkout GerritPrimer # Switch our working directory into the GerritPrimer branch
or you can do this all at once:
git checkout -b GerritPrimer # Create GerritPrimer and switch the working directory into that revision
When we are finished, our revision history looks like this:
Notice that GerritPrimer, master, origin/HEAD and origin/master branches all point to the same commit. You can think of branches is movable labels that point to a particular commit in the revision history. As we add code and commit our changes, we'll see GerritPrimer move.
Edit, commit, edit, commit, ad infinitum
Next, we'll edit some files and commit the changes. In this primer, we'll make 3 changes.
Edit ITK/Code/BasicFilters/itkRecursiveGaussianImageFilter.h add " * \see DiscreteGaussianImageFilter" on line 54
Next we ask git to show us what's happening:
revelation:ITK(GerritPrimer) blezek$ git status # On branch GerritPrimer # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: Code/BasicFilters/itkRecursiveGaussianImageFilter.h # no changes added to commit (use "git add" and/or "git commit -a")
git has the concept of an index, or an area where changes are stored before they are committed. In the listing above, git knows that Code/BasicFilters/itkRecursiveGaussianImageFilter.h is changed, but it has not yet staged that change into the index. To tell git that we want to add this change into the next commit, and make the commit we can do this in two steps:
git add Code/BasicFilters/itkRecursiveGaussianImageFilter.h # Add the modified code into the index git commit # commit all modifications
or in one step:
git commit -a # Auto-add all modified files into the index, then commit all modifications
After two more commits, our repository looks like this:
From where we made the branch (master, origin/HEAD, origin/master), we have three commits. Notice that the GerritPrimer tag has moved along with our commits.