1
This is for those who haven't used git before and need a crash-course
2
on basic operations. I'll keep this as simple as possible, and focus
3
specifically on working on Stone Soup, rather than git in general.
4
I've also added links to the official git docs at the end, which you
5
can read instead of, or in addition to this, if you're inclined.
6
7
Installing git
8
--------------
9
I strongly recommend using at least git 1.6 or later. While you can
10
use older versions, the newer versions are much more user-friendly.
11
This guide assumes you're using 1.6.
12
13
Linux: Install git using your package manager. The git package is
14
usually called git-core.
15
16
Mac: Install git using Mac ports or Fink. The MacPorts port is
17
called git-core (sudo port install git-core).
18
19
Windows: Install msysgit (http://code.google.com/p/msysgit/).
20
Be sure to download the 'msysGit-netinstall' - this is the only
21
installer used and supported by the Crawl team. TortoiseGit is
22
apparently pretty usable now for those who want Windows explorer
23
integration, but I have not used it myself.
24
25
Using git for Stone Soup development
26
------------------------------------
27
28
0. Basic git settings:
29
30
   Set your name for git to use when committing changes:
31
   $ git config --global user.name "John Doe"
32
33
   Set your email address:
34
   $ git config --global user.email "jdoe@users.sourceforge.net"
35
36
   This sets your default e-mail id for all git work on your system. You
37
   can use any e-mail address you have. In the above, John Doe is still
38
   using his old sourceforge id as a spam-catching measure.
39
40
1. Clone the crawl repository from gitorious (analogous to svn checkout):
41
42
   Developers (anyone with commit rights to the git repo):
43
   $ git clone git@gitorious.org:crawl/crawl.git
44
45
   Other users:
46
   $ git clone git://gitorious.org/crawl/crawl.git
47
48
   "git clone" clones Crawl's entire git repository to your machine. When
49
   it's done, you have a full local copy of the crawl repository with all
50
   its history.
51
52
   If you want to build the contributing libraries rather than using the
53
   versions already installed on your system, you can fetch the submodules:
54
   $ cd crawl
55
   $ git submodule update --init
56
57
2. Sanity-check your cloned repository (optional):
58
59
   When you come back to a git repository after a while, you may not
60
   recall where you cloned it from. You can check with:
61
62
   $ git remote -v
63
64
   For me, this reports:
65
   origin  git@gitorious.org:crawl/crawl.git (fetch)
66
   origin  git@gitorious.org:crawl/crawl.git (push)
67
68
   See all available branches in the repository:
69
   $ git branch -a
70
71
   See all tags:
72
   $ git tag
73
74
3. SSH keys (for core developers):
75
76
   If you want to actually push to the gitorious repository, you will
77
   need to create an ssh key and upload your public key to gitorious.org.
78
79
   Let's create an ssh key (if you already have a key, skip this
80
   step):
81
   $ ssh-keygen
82
83
   You can accept all the default options and use an empty passphrase
84
   for convenience (don't do this on an account you share with other
85
   people, or they can commit to the repository too :P)
86
87
   Once the key is generated, you'll have two files id_rsa, and
88
   id_rsa.pub in your ~/.ssh (the .ssh directory in your home
89
   directory). id_rsa is your private key, and should not be shared or
90
   given to anyone else (or they can pretend to be you); id_rsa.pub is
91
   your public key, and this is what you'll upload to gitorious.
92
93
   Go to gitorious.org, login, and hit the "Dashboard" link to access
94
   your account settings. Click on "Manage SSH keys" and then on
95
   "Add SSH key".
96
97
   Copy the one line in your id_rsa.pub, and paste it into the
98
   public SSH keys text area. Hit Save when you're done.
99
100
   Within a few minutes of uploading your key, you should be able to
101
   push/pull from gitorious.org.
102
103
   Windows users (msysgit) can follow these exact same steps in a git
104
   bash prompt.
105
106
   You can also create a DSA key instead of an RSA key (or use an
107
   existing DSA key). gitorious accepts both.
108
109
4. Updating your repository with the latest changes from gitorious.org:
110
111
   Use
112
   $ git pull
113
   to grab the latest commits from gitorious.org.
114
115
   git pull assumes your working tree is clean; it will refuse to
116
   overwrite any files that you've modified locally (unlike svn's
117
   "svn update", which will happily try to modify the file anyway,
118
   and add conflict markers if there are conflicts).
119
120
   If git pull fails because you have local changes, you have two
121
   options:
122
123
   1. Complete your local changes and create a commit, then pull
124
      again.
125
126
   2. Temporarily save (stash) your local changes, pull changes from
127
      gitorious, and reapply your local changes:
128
      $ git stash
129
      (this saves your local changes)
130
      $ git pull
131
      (grab changes from gitorious)
132
      $ git stash apply
133
      (reinstate your local changes)
134
135
      If your local changes conflict with the changes from gitorious,
136
      git stash apply will warn you of the conflict and add conflict
137
      markers to the relevant files.
138
139
5. Committing a change to the 'master' branch:
140
141
   git's master branch is the equivalent of svn trunk. Immediately
142
   after cloning a repository, the cloned crawl repo will be on the
143
   master branch. You can check what branch you're working on at any
144
   time with:
145
146
   $ git branch
147
148
   The active branch will be asterisked.
149
150
   Before starting work, let's make sure our working copy is not
151
   dirty:
152
153
   $ git status
154
   # On branch master
155
   nothing to commit (working directory clean)
156
157
   Looking good. For our first change, let's assume we're fixing a
158
   bug in, say, stuff.cc.
159
160
   $ vim stuff.cc
161
   <hackhackhack>
162
   $ make
163
   <test; that bugfix rocks the world>
164
165
   Let's check how git sees things now:
166
   $ git status
167
   # On branch master
168
   # Changed but not updated:
169
   #   (use "git add <file>..." to update what will be committed)
170
   #   (use "git checkout -- <file>..." to discard changes in working directory)
171
   #
172
   #       modified:   stuff.cc
173
   #
174
   no changes added to commit (use "git add" and/or "git commit -a")
175
176
   git sees that we've modified stuff.cc. You can see what changes
177
   you've made with:
178
179
   $ git diff
180
181
   Time to actually commit the change:
182
   $ git commit -a
183
184
   git will bring up your preferred editor for you to enter your
185
   commit message. On Windows, you may have to set your EDITOR
186
   environment variable; alternatively, you can specify your commit
187
   message on the command line:
188
189
   $ git commit -a -m "Fitted stuff.cc with warp drive"
190
191
   When you're done, your change has been committed to your local
192
   repository. Let's try git status again:
193
194
   $ git status
195
   # On branch master
196
   # Your branch is ahead of 'origin/master' by 1 commit.
197
   #
198
   nothing to commit (working directory clean)
199
200
   So git's telling us that we have one local commit that we haven't
201
   sent to gitorious' git repository yet. Let's send in our fix
202
   to gitorious.org (core devs only):
203
204
   $ git push
205
206
   You will be prompted for your password again. git should then
207
   push your commit, producing a last line that looks like:
208
209
   54ea5f1..ec2e15e  master -> master
210
211
   The exact commit ids will differ, but a successful push looks
212
   like this. Your push may fail if someone has pushed changes to
213
   gitorious already (git will warn you about a non-fast-forward).
214
   In this case, just pull and push again:
215
216
   $ git pull
217
   $ git push
218
219
6. Patching (for regular contributors, not core devs):
220
221
   Once you have commited and tested a change, you can create a patch for it.
222
   You can then send this patch to the devs or upload it to a mantis
223
   issue for review and potential addition to the game.
224
225
   To start, make and save your changes in whatever text editor you choose.
226
   Then, as explained above, commit those changes:
227
228
   $ git commit -a
229
230
   In most cases, this is a good time to compile and test the change.  Make
231
   sure it works correctly, testing in Wizard Mode as appropriate.
232
233
   When you're happy with your patch, you can make a patch file with the
234
   format-patch command.  For example:
235
236
   $ git format-patch -1
237
238
   This will create a patch from the most recent commit you've made.  The
239
   patch file will be placed in your base Crawl source directory.
240
241
   For a more detailed patch creation guide, check out patch_guide.txt in the
242
   /docs/develop/ directory.
243
244
7. Viewing revision history:
245
246
   You can see a history of changes with
247
   $ git log
248
249
   git log by itself may make it appear that the change history is a
250
   straight line, but we know that git can handle branching
251
   histories. We can request that git log show us the branching
252
   history with:
253
254
   $ git log --graph
255
256
   You can also view history using the gitk GUI (this is installed
257
   by default; everyone should have it, and I recommend it):
258
259
   $ gitk
260
261
   The history commands normally show you the history of the current
262
   branch, but you can view other branches/tags' histories by naming
263
   the branch or tag:
264
265
   $ gitk origin/stone_soup-0.2
266
   $ gitk release-0.5.1
267
268
   If you want to annotate a file with last author and commit to
269
   change each line in the file, you can use git blame, which is
270
   similar to svn blame:
271
272
   $ git blame stuff.cc
273
274
8. Committing a change to the 0.5 branch:
275
276
   So far we've restricted our attention to 'master', which is the
277
   easiest branch to work with, since it's selected by default. Now
278
   let's say we have a bug report with a 0.5.1 save, and we need the
279
   0.5 code to test the save with:
280
281
   Let's take a look at the branches we have locally:
282
   $ git branch
283
   * master
284
285
   The only local branch in our repository is master. Let's look at
286
   the branches in the remote repository (gitorious):
287
   $ git branch -r
288
     origin/HEAD -> origin/master
289
     origin/master
290
     origin/stone_soup
291
     origin/stone_soup-0.1.3
292
     origin/stone_soup-0.1.4
293
     origin/stone_soup-0.1.5
294
     origin/stone_soup-0.1.6
295
     origin/stone_soup-0.1.7
296
     origin/stone_soup-0.2
297
     origin/stone_soup-0.3
298
     origin/stone_soup-0.4
299
     origin/stone_soup-0.5
300
301
   So our local repository has a "master" branch corresponding to
302
   gitorious' "master" branch. We do not yet have a branch corresponding
303
   to gitorious' "stone_soup-0.5", so let's create the branch and switch
304
   to it:
305
306
   $ git checkout -b stone_soup-0.5 origin/stone_soup-0.5
307
   Branch stone_soup-0.5 set up to track remote branch stone_soup-0.5
308
from origin.
309
   Switched to a new branch 'stone_soup-0.5'
310
311
   master and stone_soup-0.5 are both local branches now:
312
   $ git branch
313
     master
314
   * stone_soup-0.5
315
316
   git status will also confirm that we're on 0.5 now:
317
   $ git status
318
   # On branch stone_soup-0.5
319
   nothing to commit (working directory clean)
320
321
   A quick peek at the history to make really sure we're on 0.5:
322
   $ git log
323
324
   To grab the latest changes for 0.5:
325
   $ git pull
326
327
   Ok, now we compile 0.5, test the 0.5 save and verify that a bug
328
   exists. Once we've fixed the bug, we create a commit:
329
   $ git commit -a
330
331
   Check git status:
332
   $ git status
333
   # On branch stone_soup-0.5
334
   # Your branch is ahead of 'origin/stone_soup-0.5' by 1 commit.
335
   #
336
   nothing to commit (working directory clean)
337
338
   Right, we're ready to push our fix to gitorious. But now that we
339
   have multiple local branches, let's first ask git what it plans to
340
   do when we push:
341
342
   $ git push --dry-run -v
343
   Pushing to git@gitorious.org:crawl/crawl.git
344
   Enter passphrase for key '...':
345
   To git@gitorious.org:crawl/crawl.git
346
    = [up to date]      master -> master
347
      b05bb66..976e722  stone_soup-0.5 -> stone_soup-0.5
348
349
   So git wants to push the local master and stone_soup-0.5 branches
350
   to the corresponding branches on gitorious; the master branch has
351
   no new local changes, whereas the 0.5 branch does (the new change
352
   is 976e722).
353
354
   By default, git-push will push *all* your local branches to the
355
   corresponding branches on gitorious. This is important to
356
   remember; if you had local commits on master, they would also be
357
   pushed to gitorious. This behaviour can be changed (the option
358
   is called "push.default") if it bothers you, or you can do:
359
360
   git push <remote> <local branch>:<remote branch>
361
362
   So for instance, if I am working on 'master' locally, but want to push
363
   to a remote branch called 'fixes-for-upstream', I could do:
364
365
   git push github master:fixes-for-upstream
366
367
   Once you're done working on 0.5, you can switch back to "master"
368
   with:
369
   $ git checkout master
370
371
   The next time you need to work on 0.5 again, you can return to it
372
   with:
373
   $ git checkout stone_soup-0.5
374
375
9. Common operations:
376
377
   Reverting Changes
378
   -----------------
379
   It often happens that you make a change to a file that you didn't
380
   want, or accidentally delete files that you did want. You can
381
   revert a file to its pristine version as:
382
383
   $ git checkout stuff.cc
384
385
   This also works to bring back files you accidentally deleted. If
386
   you forget these commands, "git status" will remind you:
387
388
   $ git status
389
   # On branch master
390
   # Changed but not updated:
391
   #   (use "git add/rm <file>..." to update what will be committed)
392
   #   (use "git checkout -- <file>..." to discard changes in working directory)
393
   #
394
   #       deleted:    mt19937ar.cc
395
   #
396
   no changes added to commit (use "git add" and/or "git commit -a")
397
398
   Adding New Files
399
   ----------------
400
   When committing changes with "git commit -a", newly created files
401
   won't be added to the commit unless you request it with "git add".
402
   Let's take an example:
403
404
   $ git status
405
   # On branch master
406
   # Untracked files:
407
   #   (use "git add <file>..." to include in what will be committed)
408
   #
409
   #       dwim.cc
410
   nothing added to commit but untracked files present (use "git add" to track)
411
412
   Before we commit, we must add the new file:
413
   $ git add dwim.cc
414
   $ git status
415
   # On branch master
416
   # Changes to be committed:
417
   #   (use "git reset HEAD <file>..." to unstage)
418
   #
419
   #       new file:   dwim.cc
420
421
   $ git commit -a
422
423
   In general, "git status" is your friend. It will usually tell you
424
   exactly what you need to do.
425
426
10. Branching:
427
428
   Let's say it's time to create a stable 0.6 branch. Here's how you'd
429
   do it:
430
431
   a) Branch 0.6 from master:
432
      $ git checkout -b stone_soup-0.6 master
433
434
      Let's check our local branches now:
435
        master
436
        stone_soup-0.5
437
      * stone_soup-0.6
438
439
      stone_soup-0.6 is currently a *local* branch. gitorious' git
440
      repo doesn't have it yet.
441
442
   b) Push the local branch to gitorious with a --dry-run first to
443
      make sure we're not lousing up anything:
444
445
      $ git push --dry-run -v origin stone_soup-0.6
446
      Pushing to git@gitorious.org:crawl/crawl.git
447
      Enter passphrase for key '...':
448
      To git@gitorious.org:crawl/crawl.git
449
       * [new branch]      stone_soup-0.6 -> stone_soup-0.6
450
451
      Now for the real push:
452
      $ git push origin stone_soup-0.6
453
454
   c) Point your local branch at the new branch in gitorious:
455
456
      Now that we've created the branch on gitorious, we want to set
457
      up our local "stone_soup-0.6" to get changes from gitorious'
458
      "stone_soup-0.6" when we do a git pull. We do this as:
459
460
      Tell git that stone_soup-0.6's remote repository is on gitorious:
461
      $ git config branch.stone_soup-0.6.remote origin
462
463
      And that the corresponding branch in gitorious is stone_soup-0.6:
464
      $ git config branch.stone_soup-0.6.merge refs/heads/stone_soup-0.6
465
466
      Now you can pull changes from gitorious' 0.6 branch:
467
      $ git pull
468
469
      This is only necessary for new branches that you create locally
470
      and push to gitorious. This configuration is automatically set
471
      up for you when you work with branches that already exist on
472
      gitorious.
473
474
11. Tagging:
475
476
   Once 0.6 is fit for a release, you'll need to tag it:
477
478
   $ git checkout stone_soup-0.6
479
   $ git tag -a release-0.6 -m "0.6: Now with extra kangaroos"
480
481
12. Committing changes from one major branch of development to another:
482
483
   Once we create a stable branch (say 0.5), we usually make all
484
   changes to trunk, but apply bugfixes to the 0.5 branch as well.
485
   You can apply changes from master to stone_soup-0.5 with git
486
   cherry-pick:
487
488
   $ git checkout master
489
   [ make the changes for the bugfix ]
490
   $ git commit -a
491
   $ git checkout stone_soup-0.5
492
493
   And cherry-pick the tip commit of the master branch (the bugfix
494
   we just committed there):
495
   $ git cherry-pick master
496
497
   If the commit you want to cherry-pick is not the tip of a branch, just
498
   use the commit's id:
499
   $ git cherry-pick b0ed1449
500
501
   git push will then send in the commits from both branches.
502
503
504
Additional Reading:
505
------------------
506
507
I've intentionally kept my examples very simple and glossed over a
508
lot of details. I've covered the common operations in the svn
509
workflow, but git can do much more for you if you spend a little
510
time learning it.
511
512
git documentation central:
513
http://git-scm.com/documentation
514
515
git tutorial:
516
http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html
517
518
Another crash course for svn users:
519
http://git-scm.org/course/svn.html