Unix 103: SVN commands, mostly done
[kspaans/UnixTutorial] / code-management.pod
1 =head1 UNIX 103: Code Project Management and Version Control
2
3 Chances are you're in the Computer Science program. If so, or even if you are
4 in Mathematics, it's likely that you're going to have to manage a project that
5 involves some code. This can even be true for your non-Faculty of Math courses.
6 Consider a document that contains an essay. The essay is probably mostly text
7 and some images or data or references. If you consider just the text of the
8 essay, it's a lot like code too. All of this data needs to be managed somehow.
9 Version control software (VCS), sometimes also called source code management
10 (SCM), is a powerful tool that lets you track the changes to your code over
11 time (among other things). VCS is one of the tools you are most likely to
12 encounter in the workplace if you get a job doing any kind of software
13 development. This tutorial will attempt to be as tool-agnostic as possible to
14 make it easy for you to learn any of a wide variety of VCSs. However, due to
15 the vast differences in both interface and paradigm of VCS out there, this
16 tutorial will focus on two specific programs: Git and Subversion (SVN).
17
18 For more information and in-depth tutorials, see:
19
20 =over
21
22 =item Git
23
24 L<http://git-scm.com/>
25
26 =item Subversion
27
28 L<http://subversion.tigris.org/>
29
30 =back
31
32 =head2 Terms and Definitions
33
34 All VCS uses more or less the same ideas and works for things. We will explain
35 them here.
36
37 =over
38
39 =item Repository
40
41 The I<repository> is location where all of the data and meta data used by the
42 VCS is kept: your files, different versions of your files, extra logging data
43 that describes the changes, etc. All actions performed by the VCS will happen
44 against the I<repository>.
45
46 =item History
47
48 VCS gives you a I<history> of all of the changes made to the repository. Useful
49 metadata like who made which changes to which files and when and why.
50
51 =item Diff
52
53 Because version control works with plaintext data, the common currency is the
54 I<diff>. It's a standard format that is both human and computer readable to
55 show the differences between two files. See the C<diff> utility for more
56 information, but often VCS have their own C<diff>.
57
58 =item Commit
59
60 A set of diffs get bundled into a I<commit> and saved in the repository's
61 history. The primary unit of currency in version control is the commit.
62
63 =item Patch
64
65 A patch is actually just a diff. A I<patch> can be applied to a file to make
66 the changes to that file that were described by the diff. See the C<patch>
67 utility.
68
69 =item Branch
70
71 A I<branch> is a copy of the contents of the repository. Branches can be used
72 to do non-linear development. That is, separate ideas or topics can be
73 developed in their own branches. Branches are great for doing experimental work
74 that you don't want to contaminate your main codebase with. Two branches of the
75 same code base will have identical ancestor commits somewhere in their
76 history.
77
78 =item Merge
79
80 Two branches can be I<merged> together. This will bring together the changes
81 from each branch into a single branch.
82
83 =back
84
85 =head2 Version Control in 30 Seconds
86
87 The very basics that you would want to do with your tool.
88
89 =head3 Git
90
91 =over
92
93 =item 1.
94
95 C<git init> to initialize a directory as a git repository (notice the F<.git>
96 directory that has been created)
97
98 =item 2.
99
100 C<git add> F<file> to tell git to start tracking the contents of
101 F<file>. You could also add multiple files, or say C<git add .> if you have
102 a larger group of files that you want to start tracking under version control.
103
104 =item 3.
105
106 C<git commit> will start up a text edit to let you leave an initial commit
107 message. In this message you will probably want to explain the purpose of the
108 repository, or explain the purpose of any initial files in it.
109
110 =item 4.
111
112 Now edit the file or files that git is tracking.
113
114 =item 5.
115
116 C<git add> F<file> to tell git that you like the changes you've made
117
118 =item 6.
119
120 C<git commit> and remember to leave a meaningful commit message
121
122 =item 7.
123
124 C<git log> to see the history of what you've done.
125
126 =item 8.
127
128 Goto 4.
129
130 =back
131
132 =head3 Subversion
133
134 =over
135
136 =item 1.
137
138 C<svnadmin create svn_repo> to create a subversion repository in F<svn_repo>.
139
140 =item 2.
141
142 C<svn import F<project_dir> -m "Initial commit"> to tell Subversion to add the
143 contents of F<project_dir> to the repository. In this directory should be the
144 initial files or original copy of whatever you want to start tracking under
145 version control. The C<-m> flag lets you specify the commit message.
146
147 =item 3.
148
149 C<svn checkout /path/to/svn_repo> should be done in some other directory. This
150 will checkout a working copy of the contents of the repository into a directory
151 in the present working directory called F<svn_repo>.
152
153 =item 4.
154
155 Edit your files. Use C<svn add F<file>> if you need to add I<new> files to the
156 repository.
157
158 =item 5.
159
160 C<svn commit> and remember to leave a meaningful commit message.
161
162 =item 6.
163
164 C<svn update> to resynchronize with the repository and C<svn log> to see the
165 history of what you've done.
166
167 =item 7.
168
169 Goto 4.
170
171 =back
172
173 This is really all that you need if you are working alone and want a tool to
174 keep track of metadata for you. This way when you wake up the next morning, you
175 can remember why you made those particular changes to that file last night.
176 (Assuming you knew what you were doing in the first place!)
177
178 =head2 Slightly More Advanced Usage
179
180 Making changes to your project and telling git about them is fine, but
181 sometimes you want git to tell I<you> things about your project. First, a
182 couple of definitions that are specific to git will have to be covered.
183
184 =head3 Git Definitions
185
186 =over
187
188 =item Working Directory
189
190 When you make changes to files in your respository, you are editing the
191 I<Working Directory>. Any changes will always be relative to your working
192 directory, and any playing with branch operations requires a clean working
193 directory.
194
195 =item Index
196
197 When you add files with C<git add>, they get into the I<index>. Only changes
198 which have been added to the index will be included in a commit. You can see
199 a diff of the changes in the index using the command C<git diff --cached>.
200
201 =item HEAD
202
203 Git's nickname for the latest commit in the current branch.
204
205 =back
206
207 =head3 Subversion Definitions
208
209 =over
210
211 =item Working Copy
212
213 Similar to Git's working directory, except this is the copy of the repository
214 that you have checked out. You will do all of your work, and issue all C<svn>
215 commands in the directory where your working copy is.
216
217 =head3 Get oriented with C<git status>
218
219 To find out which files have been changed, which ones have been added, and
220 which branch you are on, use the C<git status> command. It's important to note
221 that only changes that are explicitly added will be included in a commit.
222 C<git status> will show this.
223
224 =head3 Get oriented with C<svn status>
225
226 It will tell you which files have been changed. These changes, if any, will be
227 commited to the repository when you C<svn commit>.
228
229 =head3 Compare two files with C<git diff>
230
231 Typing C<git diff> at any time will print the difference between the latest
232 commit in the repository and what is in the working directory. When changes are
233 added to the index, it will show the differences between the working directory
234 and the index. To see the differences between the I<index> and the latest
235 commit, type C<git diff --cached>.
236
237 =head3 Compare two files with C<svn diff>
238
239 To compare the contents of working copy with the latest version in the
240 repository. See the changes made to only a single file with C<svn diff F<file>>.
241
242 =head3 Checking out old versions of files with C<git checkout>
243
244 The C<git checkout> command is used for checking out different versions of
245 files or for switching branches (which we will cover later). By default
246 issuing C<git checkout F<file>> will update F<file> using the contents of the
247 index. Alternatively C<git checkout I<version> F<file>> will update F<file>
248 using the contents from I<version>, which can be a commit.
249
250 E.G. C<git checkout HEAD^ hello.c>
251
252 =head3 Checking out old versions of files with C<svn revert>
253
254 The C<svn revert -r num F<file>> command is used for checking out different versions of
255 You can also fix mistakes by reverting to older versions of a file, ignoring any
256 changes made to your working copy.
257
258 =head3 Fixing Mistakes with C<git reset> and C<git revert>
259
260 Have you completely destroyed your working directory? Get it all back with
261 C<git reset --hard>. This throws away changes to the working directory and index
262 and gets the content from the latest commit to the repository. Remember that to
263 do this for a single file, use C<git checkout F<file>>.
264
265 If you are completely unsatisfied with your previous two commits worth of work
266 you can completely erase them from your repository's history with
267 C<git reset>. C<git reset --hard HEAD~2>. If you want to publicly admit to your
268 mistakes you can record this in your history by using C<git revert> instead. It
269 will create a commit specifying that you've reverted things. You will need to
270 specifically revert each commit by refering to it's commit ID.
271 C<git revert some-commit> will do this.
272
273 Did you forget something or mistype your commit message? Use
274 C<git commit --amend> to modify the most recent commit.
275
276 =head4 Warning: Modifying your History in Git
277
278 Using C<git reset> and C<git commit --amend> will modify your history. If
279 someone else has seen the state of your repository between when you made a
280 commit and when you changed the history they could get very confused! Or worse,
281 Git will get very confused.
282
283 =head2 More Advanced Usage
284
285 Some less common or more tool-specific commands.
286
287 =head3 More advanced output from C<git log>
288
289 You can see more than just author information and commit messages from
290 C<git log>. The C<--stat> option will give what is called a diffstat, showing
291 you which files have been changed. The C<-p> option, for patch, will output a
292 patch representing each commit.
293
294 =head3 More output from C<svn log>
295
296 You may find C<svn log -v> more useful.
297
298 =head3 Branches
299
300 Branching is as easy as C<git branch some-branch>. Use C<git checkout> to
301 switch branches. Branches are good for expermients or seperate topics on the
302 same code base. If an experiment is successful, you can merge it back into your
303 I<master> branch with
304  git checkout master
305  git merge some-branch
306
307 =head3 Inspecting History: Since when?
308
309 What has happened since the last three commits? C<git log HEAD^^^.. F<file>>
310 which is the same as C<git log HEAD~3.. F<file>>.
311
312 =head3 Searching Through your Code
313
314 You can search every file tracked by git in your current directory for a
315 regular expression pattern using C<git grep "pattern">.
316
317 =head2 Sharing Repositories
318
319 Without VCS, sharing development of source code would be almost impossible.
320
321 Because of Git's distributed nature, there are many ways you can setup sharing
322 of your repository. Push/pull model. Permissions.
323
324 If you set the permissions correctly when you setup your Subversion repository
325 then it is already setup for sharing. Someone else can checkout the project and
326 C<svn update> and C<svn commit>. Alternatively if you don't want to give
327 someone else write (commit) access to your repository, they can generate
328 patches with C<svn diff>.
329
330 =head3 Merge Conflicts
331
332 The biggest headache when you merge someone else's code is the conflicts that
333 can arise! When you C<git merge some-branch> Git will tell you if there are
334 conflicts:
335  kspaans@csclub:~/foo$ git merge otherbranch
336  Auto-merged blahfile
337  CONFLICT (content): Merge conflict in blahfile
338  Automatic merge failed; fix conflicts and then commit the result.
339  kspaans@csclub:~/foo$ cat blahfile
340  <<<<<<< HEAD:blahfile
341  Hello World
342  =======
343  I'm the new first line.
344  Hello, world!
345  This is the final line.
346  >>>>>>> otherbranch:blahfile
347  kspaans@csclub:~/foo$ git status
348  blahfile: needs merge
349  # On branch master
350  # Changed but not updated:
351  #   (use "git add <file>..." to update what will be committed)
352  #
353  #       unmerged:   blahfile
354  #
355  no changes added to commit (use "git add" and/or "git commit -a")
356 You can see the conflict markers that Git added, and the output from
357 C<git status> will indicate that you are in the middle of a failed merge. Fix
358 the conflicting files with your text editor and commit them. Git will have
359 included a note about the merge conflict in your commit message for you.
360
361 =head2 Disclaimer
362
363 There are a lot of really good tutorials out there. This tutorial can't hope to
364 be able to replicate them. It's merely trying to get you bootstrapped and
365 comfortable with the idea of version control, so that you can learn more on
366 your on. A starting point, if you will.
367
368 =head2 About the Authors (when they wrote this)
369
370 This document is maintained and copyright The University of Waterloo Computer
371 Science Club 2009 and is released under the terms of the Artistic Liscence
372 version 2.0 available at L<http://www.perlfoundation.org/artistic_license_2_0>.
373
374 =head3 Kyle Spaans (kspaans@student.math.uwaterloo.ca)
375
376 A 3rd year Computational Math student, Kyle has been in and around the CSC
377 since his first term at Waterloo. He's been using Linux for years now, and
378 thinks the command line and command line-based tools are important for every
379 *nix user to know.
380
381 =head2 TODO
382
383 Find out exactly which undergrad machines have git installed. Make sure that
384 svn works as expected on those same machines (or all machines).
385 Paradigm differences between git and svn.