TeamForge for Gerrit- Ready for the Enterprise

Git, Gerrit and TeamForge

In this blog, I will show you how to use GitEye with Gerrit, the most widely used code review and permissions management framework for Git.  Although GitEye will work with any Gerrit server, I will be using TeamForge for Git.  TeamForge extends and wraps Gerrit, adding centralized role-based access control (RBAC) and greatly simplifying management of Gerrit access rights.  It also provides powerful features such as history protection, making Git ready for the enterprise.

TeamForge Git Repository Configured for Optional Review

repository_definition.png

TeamForge Role-Based Access Control

rbac.png

Clone Repository

The first thing I will do is clone my TeamForge Git repository using the context menu from the CollabNet Sites view.

clone_menu_option.png

The pages of the Clone Git Repository wizard will be automatically filled, an example of how the GitEye graphical interface simplifies all Git operations.

Source Repository Location

clone_wizard_1.png

Branch Selection

clone_wizard_2.png

Local Destination Configuration

clone_wizard_3.png

Configure for Gerrit

A Gerrit repository is a wrapper for a regular Git repository.  It prevents unauthorized users from pushing directly to the Git repository.  Instead, a user who wants to submit a code change for review will push the change to a special path using the ref specification /refs/for/master.  A push to /refs/for/master triggers Gerrit to create a new review request or add a new patch set to an existing review request, depending on the Change-Id information in the commit message.

After cloning a Gerrit repository, the next step is to configure the local repository for Gerrit.  To do this, I expand the repository in the Git Repositories view.  Then I expand the Remotes node, right-click on origin and select Gerrit Configuration… from the context menu.

gerrit_config_menu_option.png

Once again, the dialog will be pre-filled with the values that I want and all I have to do is click Finish.

gerrit_config_dialog.png

What we have done is updated the push configuration to make refs/for/master the default ref specification to use when pushing changes.  To confirm this, I can expand origin, right-click on the push configuration node, and select Configure Push… from the context menu.

configure_push.png

As you can also see in the above screenshot, the repository icon has now been decorated to indicate that it is configured for Gerrit.

Create Local Branch for Change

The first thing that I do when I am ready to work on a change is create a branch for the change in my local repository.  I right-click the repository and select Switch To > New Branch… from the context menu.

new_branch_menu.png

On the Create Branch dialog, click Select…

select_source.png

Select origin/master under the Remote Tracking node and click OK.

Since I am using a TeamForge tracker and associate a work item, or artifact, with all my commits, it makes sense to use my artifact ID as the name for my new branch. I will also check Configure upstream for push and pull and I will select Rebase commits of local branch onto upstream.

create_branch.png

I leave Checkout new branch selected and click Finish.  I am now working on the artf1103 branch.

new_branch.png

In the above steps we have not only created and checked out a new branch, but we have configured Pull so that it will rebase our local commits onto upstream (origin/master).  If I am going to be working on my changes for an extended time, I will pull frequently.

pull.png

If other changes have been pushed to the remote master and perhaps caused conflicts with my local commits, I would prefer to find out about it and deal with it sooner rather than later (such as when it is time for my change to be merged).

Push Change to Gerrit

Let’s assume now that I have made some changes to source code and would like to request a review.  I will right-click on the repository and select Commit… from the context menu.

commit.png

Notice the Change-Id row in the commit message.  When we configured the repository for Gerrit, a flag was added to the repository that tells GitEye to add this automatically.  The Change-Id is what uniquely identifies a Gerrit change.  I0000000000000000000000000000000000000000 is a special value used to indicate a new Gerrit change.  When the commit takes place, this will be replaced by the actual ID that is generated by Git.

I will go ahead and click Commit and Push.  Because the repository has been configured for Gerrit, I can accept all the default values on each page of the push wizard.

Destination Git Repository

dest.png

Push Ref Specifications

ref_specs.png

Push Confirmation

conf.png

Review Change Request

Once the changes are pushed to Gerrit, a change request is created.  I can view and work with it from either the Gerrit web ui or from directly in GitEye, which includes a rich change request editor.  In this case I have gone to the CollabNet Sites view and expanded my TeamForge server node and the Gerrit node.  Then I expanded one of the built-in Gerrit queries to reveal the change request.  When I double-click the request, or right-click it and select Open with > Editor, it is opened in the Gerrit change request editor.

invite.png

Once my change request has been created I can wait patiently for authorized users to review it, or I can click on Add Reviewers… and invite specific users to do a review.  In the above screenshot, I’ve done the latter.

Let’s suppose that the user who I have invited has reviewed my changes using Gerrit’s side-by-side display and determined that something is missing.  He clicks on the Review utton (this time I am showing the Gerrit web UI).

review_2.png

Then he gives the change a -1 and adds a comment explaining why he would prefer that the change not be submitted.

rejected.png

There are a few things worth noting in the above screenshot.

  1. The word submit in this context basically means merge.  When a change is approved and submitted, it is merged into the code base.  In this case, since the reviewer is voting against the change, he will click Publish Comments.
  2. A user with sufficient permissions can give a change a +2 and submit it right away, but it is normally preferable that at least two users review a change before it is merged.
  3. A -1 vote is typically used to indicate that you agree with the change in general, but you think that it still needs work before being submitted.  A -1 vote is cleared when the change is updated with a new patch set.  A -2 vote, however, is not removed when a new patch set is uploaded.  It is typically used to indicate that you disagree with the change in principal, and it remains unless it is explicitly revoked.
  4. There are two sections where a vote can be cast, the Verified section and the Code-Review section.  In this blog I am focusing on the Code-Review section.  This is where peer review of your code takes place.  A vote in the Verified section does not mean that the code makes sense, that it does what it’s supposed to do or that it adheres to your project’s coding standards.  It simply means that it works, which typically equates to “it does not break the build”.  With TeamForge, Gerrit can be configured such that a pushed change automatically triggers a Jenkins build and the Jenkins build in turn automatically casts a -1 or +1 verification vote depending on whether the build fails or succeeds.  If you are interested in learning more about how TeamForge, Gerrit and Jenkins work in concert, you will find an excellent webinar here.

Update Review with New Patch Set

Having been notified that my changes need some work, let’s assume that I’ve read the reviewer’s comments (which can be at the change level, but can also be associated with individual lines of code) and I know exactly what I need to fix in my code.  However, take a close look at my workspace.

work.png

While I was waiting for my changes to be reviewed, I have not been sitting on my hands.  I have created a new branch (artf1104) for another work item that I have been assigned, and I have started to do work in that branch.  Before I fix the problems that were found during code review, I will switch back to the branch from which I pushed the change.

switch.png

Now let’s assume that I have fixed my code.  Again, I right-click on the repository and select Commit…

commit.png

This time, and this is very important because Gerrit will reject a push of a commit if it contains the same Change-Id as a predecessor commit, I click on the Amend Previous Commit icon (first icon above the commit message).  The commit message is populated with my previous commit message, with the Change-Id resolved, as shown above.  When I click Commit and Push, a second patch set will be added to my change request.

patch_set.png

This time my change is approved.

approve.png

When the reviewer clicks Publish and Submit, Gerrit merges my change into the code base.

merged.png

Fetching a Change from Gerrit

At times it is useful to pull a change from Gerrit into a local repository.  Perhaps, as a reviewer, I want to run the actual code locally and maybe step through the code in debug mode.  Or perhaps the user who made the change request is no longer available to work on it, or is not qualified to make the follow up changes suggested by reviewers.

To pull a change from Gerrit using the command line, I would do something like this:

git pull ssh://elsemore@cu038.cloud.sp.collab.net:29418/eclipse_desktop refs/changes/05/5/1

The GitEye UI, however, makes this very easy.  I right-click on the repository and select Fetch from Gerrit…

fetch_from_gerrit.png

In the Fetch a Change from Gerrit dialog, I can use Ctrl+Space in the Change field to select from a list of existing changes.  When I select a change, the dialog fields will be filled in so as to generate the appropriate fetch request, including a logical name for the local branch to be created and checked out.

fetch_from_gerrit_dialog.png

Once I have the change, I can tweak it as necessary.  When I am ready, I will amend the previous commit, as shown earlier in this blog, and push to Gerrit, resulting in a new patch set being added to the change.

Note

If you are adding a new patch set to another developer’s change request, as described above, then you should be sure to coordinate this activity with the original author so that you don’t both end up doing the same (or conflicting) work.

Bypassing Code Review

If I am authorized to do so, I can skip code review and push directly to the code base.  To do this, I right-click on the repository and select Remote > Push

remote_push.png

When the push wizard is shown, click Next to go to the Push Ref Specifications page.

push_1.png

Click the remove icon to remove the refs/for/master spec.

push_2.png

In the Source ref dropdown, select the master branch.  The screen will look like this:

push_3.png

Click the Add Spec button to add the ref specification.

push_4.png

Leave the Save specifications in ‘origin’ configuration checkbox unselected.  We only want to override this particular push to go directly to the code base; we want the default ref specification to remain refs/for/master so that future pushes will continue to result in Gerrit change requests.

Click Finish to push directly to the code base.

Conclusion

I hope this blog will be helpful if you are getting started with Gerrit and GitEye.  Before closing, there is one last important thing that I would like to stress.

One patch set corresponds to exactly one Git commit.

Lack of understanding of this concept is a primary source of confusion and frustration for many if not most new Gerrit users.

If you want to commit your work periodically as you prepare a change request, then always amend the previous commit!

If you have forgotten to or chosen not to do this and your changes now consist of multiple commits, then you must squash these commits before you can push to Gerrit.  You do this using interactive rebase.  Interactive rebase is beyond the scope of this article but, since GitEye is built on top of EGit, you can learn about it in the EGit user guide, here.

Steve Elsemore

Steve Elsemore is a Sr. Software Engineer at CollabNet. He works on Subclipse, GitEye and the CollabNet Desktop - Eclipse Edition.

Tagged with: , , , ,
Posted in Agile, CloudForge, Git, TeamForge
One comment on “TeamForge for Gerrit- Ready for the Enterprise
  1. Jonas Christensen says:

    Just installed CollabNet GitEye, and I’m sorry to find that (as with Atlassian SourceTree) the Amend functionality does not list the file/change content of the commit, it only shows the commit message.

    This effectively means that an Amend can only add to a commit, not remove from it (as the native Git Gui are able to).

    Also this means that you do not see the entire changeset that you are about to commit, you just see the changes which you have added on top.

    I’m baffled why both CollabNet and Atlassian has chosen to change native Git functionality, and effectively reduce the featureset.

    Br,
    Jonas Christensen

Leave a Reply

Your email address will not be published. Required fields are marked *

*

CAPTCHA Image

*

connect with CollabNet
   Contact Us
Subscribe

Have new blog posts sent directly to your email.

looking for something
conversations

CloudForge: Join #CollabNet for the TeamForge® 8.1 release webinar and learn about its new powerful enterprise #Git features http://t.co/IHfnkoEfGr
Date: 1 September 2015 | 5:00 pm

CloudForge: Join this #CollabNet #webinar and learn how to reduce server loads with #Git replication and improve Git performance http://t.co/pB1DEsWFPh
Date: 31 August 2015 | 6:00 pm

CloudForge: Seamlessly integrate #Git upstream and downstream to tools such as #Jira and #Jenkins on this #CollabNet #webinar http://t.co/pB1DEsWFPh
Date: 28 August 2015 | 5:30 pm