none
[openafs-wiki.git] / AFSLore / GitDevelopers.mdwn
1 # <a name="Git and gerrit for developers"></a> Git and gerrit for developers
2
3 Git opens up a number of new options for contributing to OpenAFS. For the first time, it is easy to review code that is pending addition to the OpenAFS tree. In fact, reviewing code is one of the best ways to ensure that the releases that OpenAFS ships remain stable and functional. If you are interested purely in reviewing, then please skip to that section towards the end of this document.
4
5 Git also changes the way that developers interact with the OpenAFS tree. Instead of just having a single version of the tree on your local machine, you have a compressed copy of the entire repository. Additionally, you no longer have to produce patches to send code upstream - any developer can push into the OpenAFS repository directly, through gerrit, our code review tool.
6
7 Whilst git is a far more powerful tool than CVS it is also, inevitably, more complex. This document can only scratch the surface of what's possible with git - there are many, many, documents available that describe git in greater detail, and references to some of them are provided at the end.
8
9 ## <a name="Getting git"></a> Getting git
10
11 Firstly, if your machine doesn't already have it installed, get a copy of the 'git' version control system. This is available for many platforms from their upstream package repositories or, failing that, can be downloaded in both source and binary form from <http://git-scm.com/download>
12
13 ## <a name="Getting the _OpenAFS repository"></a> Getting the OpenAFS repository
14
15 You can download the entire OpenAFS repository by running
16
17     git clone git://git.openafs.org/openafs.git
18
19 to place the clone in a directory called 'openafs' or
20
21     git clone git://git.openafs.org/openafs.git <name-of-directory>
22
23 to place your clone in a specific directory
24
25 This will give you a complete copy of the OpenAFS repository and unless you are exceptionally short of either disk space, or time, is the approach we recommend. Unlike CVS, you are not just checking out a particular branch, but making a local copy of the project's whole revision history, across all of it's branches. This does make the download pretty large - around 150Mbytes at the time of writing.
26
27 ## <a name="Updating the local copy"></a> Updating the local copy
28
29 When you want to update the local repository with the central OpenAFS one, running
30
31     git pull
32
33 will pull all of the new changes into your local repository, and merge those changes into your correct working tree. Note that whilst this is fine when you are browsing the repository, you may want to exercise more control over how upstream changes are merged into your development code.
34
35 ## <a name="Checkout a particular branch"></a> Checkout a particular branch
36
37 The OpenAFS repository contains many branches, most of which are historical and should not be used for new development. Current development should be targetted at 'master' (for feature work, and general bugfixing), or at 'openafs-stable-1\_4\_x' (bug fixes specific to the current stable release). Note that the openafs-devel-1\_5\_x branch is now effectively dead - future 1.5 releases will occur from the 'master' branch.
38
39 A complete list of all branches can be obtained by running
40
41     git branch -r
42
43 If all you wish to do is browse code, then you can directly check out these remote branches, using
44
45     git checkout origin/<branch>
46
47 For example, to checkout the 'openafs-stable-1\_4\_x' branch:
48
49     git checkout origin/openafs-stable-1_4_x
50
51 Note that if you wish to do development, you should either make a local branch which tracks the remote one, using something like
52
53     git checkout -b openafs-stable-1_4_x origin/openafs-stable-1_4_x
54
55 or, more simply
56
57     git checkout --track origin/openafs-stable-1_4_x
58
59 or by creating a topic branch as discussed below.
60
61 ## <a name="Checkout a particular release"></a> Checkout a particular release
62
63 Every release version of [[OpenAFS]] is marked in the repository by means of a tag.
64
65 A complete list of all tags can be obtained by running
66
67     git tag
68
69 To checkout a particular tag
70
71     git checkout openafs-stable-1_4_10
72
73 Again, whilst a direct checkout of a remote tag is fine for code browsing, it should not be used as a place to start development. If you must do development against a tag, then create a local topic branch with it as a starting point, as is discussed below. However, in general, please don't develop from a particular tag, but instead work from a branch tip. It makes it much easier to integrate your changes!
74
75 ## <a name="Viewing deltas"></a> Viewing deltas
76
77 In git, a delta should be simply a single changeset. Deltas are represented by means of a special form of git tag, allowing you to locally view the change, and commit message, that corresponds to each one. In order to keep down the transfer size, deltas are not included in the repository you get when you do a git clone - there are over 10,000 delta references, and having them in your local repository can cause performance issues. If you really wish to be able to locally browse deltas, then run the following
78
79     git config --add remote.origin.fetch '+refs/deltas/*:refs/remotes/deltas/*'
80     git fetch origin
81
82 You can then view a specific delta by doing
83
84     git show refs/remotes/deltas/<branch>/<delta>
85
86 Sadly, historical accidents mean that not all of our deltas can be represented by means of single commit. Where this is the case, a delta-name will have a trailing -part-, where each of these numbers must be used to form the complete delta. This only applies to some deltas created before the git conversion - all deltas created from now on will be a single changeset.
87
88 ## <a name="Introducing yourself to git"></a> Introducing yourself to git
89
90 Before you begin development, you should let git know who you are. This provides it with a name, and email address, that is used to attribute all commits in your repository, and in any that you share code with.
91
92     git config user.name "Joe Bloggs"
93     git config user.email "joe.bloggs@example.org"
94
95 If you want to make this settings for all of your repositories, then add the --global switch.
96
97     git config --global user.name "Joe Bloggs"
98     git config --global user.email "joe.bloggs@example.org"
99
100 Note that this email address is the address by which you will be identified in [[OpenAFS]]'s revision history - it is also the address to which the gerrit code review tool will send all email related to the review of your code.
101
102 ## <a name="Starting development"></a> Starting development
103
104 We strongly recommend that you do all of your development upon 'topic branches' This allows you to isolate multiple unrelated changes, and makes it easier to keep your tree in sync with the upstream [[OpenAFS]] one.
105
106 Before creating a new topic branch, running
107
108     git fetch
109
110 will make sure that your repository is up to date (unlike git pull, this will not update any files that you may have checked out)
111
112 To create a new topic branch:
113
114     git checkout -b <branch>
115
116 For example, to work on a patch to fix printf warnings, based on the current development code, I would do:
117
118     git checkout -b fix-printf-warnings origin/master
119
120 This puts me on a new branch, ready to start writing code. We'd strongly recommend that all new development is based upon the origin/master branch, submissions based upon other branches are unlikely to be accepted.
121
122 'git add' is used to tell git about any new files you create as part of your patch. If your patch results in any new compilation products (object files, new executables, etc) that git should not be tracking, please make sure that they're caught by the .gitignore mechanism. You can do this by checking that they don't appear in the output from 'git status'
123
124 'git mv' and 'git rm' are used to move and delete files respectively.
125
126 'git commit -a' is used to commit code to all of the files that git is currently tracking (that is, all of the files that you have checked out from the repository, and all those which you have run git add on)
127
128 ## <a name="When you can&#39;t see the wood for"></a><a name="When you can&#39;t see the wood for "></a> When you can't see the wood for the trees
129
130 If, in the middle of development, you discover that you've gone down a blind alley, and wish to go back to the state of your last commit
131
132     git reset --hard
133
134 will discard all of the changes you have made since the last commit, or
135
136     git checkout -f <file>
137
138 will restore &lt;file&gt; to the state it was in at the last commit.
139
140 ## <a name="Keeping up with the Jones&#39;"></a> Keeping up with the Jones'
141
142 If you're working on a long running development project, you will find that the point your created your topic branch rapidly recedes into history. At some point (and at least before you share your code with us), you'll probably want to update your tree. There are a number of ways of doing this.
143
144 If you haven't shared you tree with anyone else, then you can use
145
146     git rebase <branch> <topic>
147
148 (Where &lt;branch&gt; is the name of the upstream branch - for example origin/master, and &lt;topic&gt; is the name of the topic branch you are currently working on)
149
150 Note that git rebase changes your local history (it moves the branch point of your topic branch to the tip of the upstream branch), and is a bad idea if others have cloned your repository. See 'man git-rebase' for more details.
151
152 If you can't rebase, then consider either merging the changes onto your local branch, or creating a new topic branch and cherry picking your changes onto it. The man pages for 'git merge' and 'git cherry-pick' provide more detail on these options.
153
154 ## <a name="Sharing your code with us"></a> Sharing your code with us
155
156 How you work from this point onwards depends on how you intend making your code available to OpenAFS. We're still happy to receive submission by patch (by sending your changes to <openafs-bugs@openafs.org>), but it makes it much easier for us if you push directly from your git tree to our code review system, gerrit.
157
158 ## <a name="Registering with gerrit"></a> Registering with gerrit
159
160 To register with gerrit, visit <http://gerrit.openafs.org/> and log in using any OpenID. OpenIDs are available from a large number of internet services, including Google Accounts. If you don't have one, <http://myid.net> is an OpenID provider that we know works with Gerrit, and that don't require much in the way of personal details to obtain an account. Note that we're aware of problems using LiveJournal OpenIDs to access the service.
161
162 If, when you introduced yourself to git, you gave it a different email address than the one gerrit currently has listed for you, you need to introduce yourself to gerrit under that name, too. Click on 'Contact Information', and select "Register New Email...". If gerrit thinks you are an "Anonymous Coward" then you can fix that on this page as well.
163
164 In order to be able to upload code, you now need to create a ssh key that gerrit can use to identify you, or tell gerrit about one that already exists.
165
166 To create a new ssh key, if you don't already have one, run
167
168     ssh-keygen -t rsa -f ~/.ssh/id_rsa
169
170 The public key for this is now stored in ~/.ssh/id\_rsa.pub.
171
172 To tell gerrit about your key, log in, and go to 'Settings'. Select 'SSH Keys', and paste your _public_ key into the "Add SSH Public Key" box, or click on the 'Open Key...' option to load it from the filesystem. Click on 'Add' to add the new public key. While you are on this page, make a note of your 'SSH Username', because you'll need to for the next step.
173
174 To make things easier, set up OpenSSH so that it knows about the defaults for the gerrit server. Edit ~/.ssh/config, and add a section like:
175
176     Host gerrit.openafs.org
177     User <SSH Username>
178     IdentityFile ~/.ssh/id_rsa
179     Port 29418
180
181 (where SSH Username is what you were told on the the 'SSH Keys' page)
182
183 ## <a name="Uploading to gerrit"></a> Uploading to gerrit
184
185 When submitting to gerrit, it's important to realise that each commit in your branch will become a changeset in the upstream OpenAFS, typically with no modification at our end. It is therefore important that these commits follow some simple rules...
186
187 First, each commit should be complete. The maxim "one change per commit, one commit per change" applies here. Each commit should build and test in its own right. Typically, this means that a change will be in a small number of commits. If, during development, you have created many more than this (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.
188
189 Secondly, each commit should have a meaningful revision log. The internals of git means that we can't easily edit these before pushing them into the tree, so we'd like you to get them right for us! A commit message should be comprised of a single 'subject' line (which must **not** end with a full stop), followed by a blank line, followed by one or more paragraphs explaining the purpose of the patch. If it is intended to fix a bug in OpenAFS RT, then the word 'FIXES' followed by the bug number or comma-separated list of bug numbers should be included on a line of its own. The 'LICENSE' keyword can be used to indicate code which is covered under a license other than the IPL, although please speak to a gatekeeper if you intend using this. An example commit message would be
190
191       Add option to disable syscall probing
192
193       This adds the --disable-linux-syscall-probing to allow the probing of
194       kernel memory for the syscall table to be disabled at compile time. This
195       helps with Linux architectures which have compile, run or load time
196       issues with syscall probing by providing a band-aid fix until we can
197       improve the configuration logic in this area.
198
199       FIXES 123456
200
201 Once you have commits in this form, use
202
203     git log -p <branch>..HEAD
204
205 (where &lt;branch&gt; is the upstream branch upon which you are basing this patch)
206
207 to check that what you're giving us makes sense. Then, upload them to gerrit using
208
209     git push ssh://gerrit.openafs.org/openafs.git HEAD:refs/for/<branch>
210
211 (again &lt;branch&gt; 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)
212
213 In this case, refs/for is a literal string. So, if you had been developing against master, you can upload your changes with:
214
215     git push ssh://gerrit.openafs.org/openafs.git HEAD:refs/for/master
216
217 This relies upon the ssh configuration you performed earlier. If it fails to work, please consult the troubleshooting notes at <http://gerrit.googlecode.com/svn/documentation/2.0/user-upload.html>
218
219 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.
220
221 ## <a name="Revising your change"></a> Revising your change
222
223 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. 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 with
224
225     git push ssh://gerrit.openafs.org/openafs.git <hash>:refs/changes/<number>
226
227 (where &lt;hash&gt; is the sha1 hash of the revised change, and &lt;number&gt; is the change number you received when you originally submitted the patch)
228
229 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)
230
231 Other mechanisms of listing the change to push are available - see <http://gerrit.googlecode.com/svn/documentation/2.0/user-upload.html> for full details.
232
233 ## <a name="Updating your change"></a> Updating your change
234
235 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.
236
237 You can do this with
238
239     git rebase origin/master <topic>
240
241 (assuming your patch is against the 'master' git branch, and lives on the &lt;topic&gt; branch)
242
243 And then simply resubmit your change in the same way as if you had been asked to revise it (see notes above)
244
245 ## <a name="Submitting by patch"></a> Submitting by patch
246
247 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.
248
249     git diff HEAD
250
251 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,
252
253     git diff master..<topic>
254
255 will give all of the changes between the branch point of you topic branch (assuming you branched from 'master') and the last commit.
256
257 You can send those into <openafs-bugs@openafs.org> 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?
258
259 ## <a name="Reviewing changes"></a> Reviewing changes
260
261 We'll now look at how changes that have made it into gerrit can be reviewed. All code review now happens via the <http://gerrit.openafs.org> interface. You should log in there as detailed above (using any OpenID), and make sure that the email address points to somewhere you'll read regularly.
262
263 You'll be presented with a list of patches requiring review or, if someone has asked, patches you've been explicitly requested to review. There are two types of review - Code Review and Verification. Code Review means that you have read through the code, and are satisified that it works properly, follows the tree's style, and generally doesn't suck. Verification means that you have taken a copy of the patch and tested it. We hope to eventually automate the verification step, but for now both must be perfomed by hand.
264
265 To perform a code review, go through each of the diffs in the current changeset for the code you have decided to review. You can double click on a line to leave a comment. Once you have completed commenting, click on the 'Publish Comments' button on the page containing the list of patch sets. You will then be asked to score the patch, with a range from -1 to +1. -1 means that you don't think the code should be applied, +1 means that it is good to apply. You can also leave further, general, comments for the patch submitter.
266
267 Note that no matter how many +1 or -1 comments a patch receives, the gatekeepers can override these to either permit or forbid submission. Also, at least one gatekeeper must approve a patch before it can be submitted to the tree.
268
269 To verify the code, pull the git copy into your local tree, using the git command listed as part of the patch details. For sanity's sake, we'd strongly recommend you do this pull into a topic branch you've created for the purpose. Build it, test it, and report your results. Note that a single -1 to verification can block patch submission, so please use these options wisely. If in doubt, score 0 and leave your comments. Please indicate when verifying which platforms you have tested on, and what testing you performed.
270
271 And that's pretty much it. All of this is very new. If you encounter any problems at all, please ask for help on IRC in #openafs, Jabber in <openafs@conference.openafs.org> or on <openafs-devel@openafs.org>. Private pleas may be addressed to <simon@sxw.org.uk>
272
273 ## <a name="Further Reading"></a> Further Reading
274
275 Git Magic <http://www-cs-students.stanford.edu/~blynn/gitmagic/>
276
277 Git User's Manual <http://www.kernel.org/pub/software/scm/git/docs/user-manual.html>
278
279 Git Community Book <http://book.git-scm.com/>
280
281 Gerrit Documentation <http://gerrit.googlecode.com/svn/documentation/2.0/index.html> (only the first 'User Guide' section of this document is relevant)
282
283 ## <a name="Acknowledgments"></a> Acknowledgments
284
285 Thanks to everyone who has reviewed this document, and offered corrections and contributions.
286
287 -- [[SimonWilkinson]] - 07 Jul 2009