Working with Gerrit as a Developer
Version 8 (Michael Sauter, 2010-11-23 13:57) → Version 9/12 (Karsten Dambekalns, 2011-02-22 15:55)
h1. Working with Gerrit as a Developer
How you work from this point onwards depends on how you intend making your code available to us. We're still happy to receive submission by patch (attach the patch to the issue you created or worked on using the Forge), but it makes it much easier for us if you push directly from your git tree to our code review system, gerrit.
h2. Uploading to gerrit
h3. The Change-Id hook
Gerrit introduces the concept of "Change IDs". This is a unique reference for a particular change, which remains constant regardless of any changes that are made to the implementation. This allows a single reference to be attached to a given modification, irrespective of any rewrites that may occur as a result of review comments. Manually maintaining change ids is a pain, so gerrit provides a git hook which can be used to automatically add a change id to any new modifications you create.
Because hooks cannot be transferred with a clone of a project, you must copy them to your @.git/hooks@ directory and make them executable. The hook can be downloaded from the gerrit server by running the following in the top level of your git tree
<pre>scp -p -P 29418 USERNAME@review.typo3.org:hooks/commit-msg .git/hooks/</pre>
*Do this for every working copy you clone!* Make sure the hook is marked as executable after it is installed (scp should take care of this)!
When using a superproject with submodules, you can use this to install the hook for every submodule:
<pre>git submodule foreach 'scp -p -P 29418 USERNAME@review.typo3.org:hooks/commit-msg .git/hooks/'</pre>
If you cannot use scp (you should, it takes care of permissions automatically!), you can download the hook via HTTP, e.g. using @curl@, @wget@ or a browser, from
<pre>https://review.typo3.org/tools/hooks/commit-msg</pre>
*Windows users*: If you are using msysgit, the hook and scp work as shown here, simply use the git shell included with msysgit.
h3. Pushing to gerrit
When submitting to gerrit, it's important to realise that each commit in your branch will become a changeset in the upstream codebase, typically with no modification at our end. It is therefore important that these commits follow some simple rules...
*Each commit should be complete.* The rule "one change per commit, one commit per change" applies here. Each commit should build and test in its own right. If, during development, you have created multiple commits for a change (for example, you've created a large number of bug fix commits), please use 'git rebase', or cherry pick these commits into a separate tree before uploading them.
*Each commit should have a meaningful revision log message.* We can't easily edit these before pushing them into the tree, so we'd like you to get them right for us! Here are the [[FLOW3 commit message rules for Git]], explaining in detail this example:<pre>[~TASK] FLOW3 (MVC): Fix the foobar problem when using baz
The foobar was not corrently fumbled when using baz, now this works as
expected.
Resolves: #345
Related: Relates to: #789</pre>
Once you have commits in this form, use<pre>git log -p origin/<branch>..HEAD</pre>(where <branch> is the upstream branch upon which you are basing this patch) to check that what you're giving us makes sense.
Make sure the Change-Id line is in the commit message(s), if it is not, check the commit-msg hook and amend the commit to get the Change-Id in.
*Be nitpicky and precise, please! Better safe than sorry!*
Then, upload them to gerrit using
<pre>git push ssh://review.typo3.org/<projectname> HEAD:refs/for/<branch></pre>
(again <branch> is the name of the upstream branch that you are pushing the changes into, not the name of any local branch you may have been developing on).
In this case, 'refs/for' is a literal string. So, if you had been developing against master, you can upload your changes with:
<pre>git push ssh://review.typo3.org/<projectname> HEAD:refs/for/master</pre>
This relies upon the ssh configuration you performed earlier. If it fails to work, please consult the "gerrit troubleshooting notes":https://review.typo3.org/Documentation/user-upload.html
Assuming all has gone well, this will have added the entry to the code review queue. The output from git review will give you a change number - this is a unique reference for this particular set of changes. During review you'll be emailed with any comments anyone makes, and can respond to those comments using the gerrit web interface (see the section on reviewing, below). It's possible that issues with your change may be noticed during the review process, and you may be asked to revise it, or update changes to the tip of the tree.
To make life easier, you can add the review server and the needed refspec to your clone's @.git/config@ file like this:
<pre>
git config remote.origin.push HEAD:refs/for/master
git config remote.origin.pushurl ssh://review.typo3.org/<projectname>
</pre>
This will create a configuration like this:
<pre>[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = git://git.typo3.org/<projectname>.git
pushurl = ssh://review.typo3.org/<projectname>
push = HEAD:refs/for/master
</pre>
Then you can use a simple
<pre>git push</pre>
to submit a change to gerrit.
Depending on your setup it may help to include username and port in the @pushurl@ to be picked up by some tools (like SmartGit).
h3. Revising your change
It's possible that your modifications won't be accepted first time. In this case, you need to revise your changes, and resubmit them to gerrit. Please note that this should always be done by modifying your original changeset, not by submitting a new change that makes the required fixes.
If you use topic branches, switch to the according branch. If you no longer have the branch or didn't use a topic branch, you can check out the needed state using the information shown for the change in gerrit.
After you fixed your change, either @git commit --amend@, or @git rebase@ should be used to combine your changes with the original changeset, and then you should push this to gerrit like you did before:
<pre>git push ssh://review.typo3.org/<projectname> HEAD:refs/for/<branch></pre>
The @Change-Id@ lines in the commit message will be used to match the commit to the existing review entry.
If no @Change-Id@ was present in the entry, things get more complicated. To add an additional patch set to a change, replacing it with an updated version of the same logical modification, send the new commit to the change's ref. For example, to add the commit whose SHA-1 starts with @c0ffee@ as a new patch set for change number 1979, use the push refspec @0ffee:refs/changes/1979@ as below:
<pre>git push ssh://review.typo3.org/<projectname> c0ffee:refs/changes/1979</pre>You can obtain the sha1 hash of a commit by using 'git show' (if it is on the tip of your current branch), or 'git log' (if it is in your history). *This method is considered deprecated in favour of @Change-Id@ lines!*
Make sure to read the "documentation on uploading changes":https://review.typo3.org/Documentation/user-upload.html for details.
h3. Updating your change
It's possible that your change may have been made against a tree which is too old for it to apply to the tip. In this case, gerrit will let you know that there is a collision, and request that you update the change to the tip.
You can do this with
<pre>git rebase origin/master <topic></pre>
(assuming your patch is against the 'master' git branch, and lives on the <topic> branch).
And then simply resubmit your change in the same way as if you had been asked to revise it (see notes above)
h2. Submitting by patch
If all of this seems too daunting (and please don't let it put you off) you can still, of course, submit patches by email.
<pre>git diff HEAD</pre>
will give you the set of changes if you don't do local commits. If you make topic branches, and commit things locally, but don't want to go through the whole gerrit process,
<pre>git diff master..<topic></pre>
will give all of the changes between the branch point of you topic branch (assuming you branched from 'master') and the last commit.
You can attach those to issues in the Forge issue trackers as before. Note, however, by doing this you're making someone else take the patch, create a topic branch in their local tree, apply the patch, and push it into gerrit.
*Things would be much more efficient if you pushed into gerrit yourself. Please?*
h3. Committing Patches
Patches sent in or attached to the issue tracker still need to be committed and pushed by someone. To commit a patch, make a new topic branch, and apply the patch to that branch. When committing, use
<pre>git commit --author="A.N. Author <an.author@example.org>"</pre>
to acknowledge the patch author (your name will still be there as the committer of the patch). Push the patch into gerrit as usual, and wait for reviews ...