bgneal@1
|
1 .. role:: strike
|
bgneal@1
|
2 :class: strike
|
bgneal@1
|
3
|
bgneal@0
|
4 Introduction to Distributed Version Control with Mercurial
|
bgneal@0
|
5 ==========================================================
|
bgneal@0
|
6
|
bgneal@0
|
7 ----
|
bgneal@0
|
8
|
bgneal@1
|
9 (Sublimal Message)
|
bgneal@1
|
10 ==================
|
bgneal@1
|
11
|
bgneal@4
|
12 .. image:: images/stop.jpg
|
bgneal@1
|
13
|
bgneal@1
|
14 ----
|
bgneal@1
|
15
|
bgneal@0
|
16 # whoami
|
bgneal@0
|
17 ========
|
bgneal@0
|
18
|
bgneal@0
|
19 Brian Neal <bgneal1@rockwellcollins.com>
|
bgneal@0
|
20
|
bgneal@0
|
21 Started at Rockwell Collins in July 1999
|
bgneal@0
|
22
|
bgneal@5
|
23 You might remember me from the following programs:
|
bgneal@0
|
24
|
bgneal@0
|
25 - UMS (July 1999 - Spring 2000)
|
bgneal@0
|
26 - Surgical Strike - (Spring - Fall 2000)
|
bgneal@0
|
27 - JTRS 2B - (Fall 2000 - Summer 2001)
|
bgneal@0
|
28 - SCAMP SEP - (Summer 2001 - October 2004)
|
bgneal@0
|
29 - TTNT (January 2005 - Present)
|
bgneal@0
|
30
|
bgneal@0
|
31 ----
|
bgneal@0
|
32
|
bgneal@0
|
33 Brief History of Version Control Tools
|
bgneal@0
|
34 ======================================
|
bgneal@0
|
35
|
bgneal@0
|
36 First Generation
|
bgneal@0
|
37 ----------------
|
bgneal@0
|
38
|
bgneal@1
|
39 - No networking!
|
bgneal@1
|
40 - Concurrency method: locks
|
bgneal@0
|
41 - Examples:
|
bgneal@0
|
42
|
bgneal@0
|
43 - SCCS - 1972
|
bgneal@0
|
44 - RCS - 1982
|
bgneal@0
|
45
|
bgneal@0
|
46 ----
|
bgneal@0
|
47
|
bgneal@0
|
48 Brief History of Version Control Tools
|
bgneal@0
|
49 ======================================
|
bgneal@0
|
50
|
bgneal@0
|
51 Second Generation
|
bgneal@0
|
52 -----------------
|
bgneal@0
|
53
|
bgneal@0
|
54 - Client/Server networking; CVCS (Centralized Version Control)
|
bgneal@1
|
55 - Concurrency method: merge before commit
|
bgneal@0
|
56 - Examples:
|
bgneal@0
|
57
|
bgneal@0
|
58 - CVS - 1990
|
bgneal@0
|
59 - IBM Rational ClearCase - 1992
|
bgneal@0
|
60 - Visual SourceSafe - 1994
|
bgneal@0
|
61 - Perforce - 1995
|
bgneal@0
|
62 - SVN - 2000
|
bgneal@0
|
63
|
bgneal@0
|
64 ----
|
bgneal@0
|
65
|
bgneal@0
|
66 Brief History of Version Control Tools
|
bgneal@0
|
67 ======================================
|
bgneal@0
|
68
|
bgneal@0
|
69 Third Generation
|
bgneal@0
|
70 ----------------
|
bgneal@0
|
71
|
bgneal@0
|
72 - Distributed networking; DVCS (Distributed Version Control)
|
bgneal@1
|
73 - Concurrency method: commit then merge
|
bgneal@1
|
74 - Examples:
|
bgneal@0
|
75
|
bgneal@0
|
76 - Bitkeeper - 2000
|
bgneal@0
|
77 - Darcs - 2003
|
bgneal@0
|
78 - Monotone - 2003
|
bgneal@0
|
79 - Git - 2005
|
bgneal@0
|
80 - **Mercurial** - 2005
|
bgneal@0
|
81 - Fossil - 2006
|
bgneal@0
|
82 - Bazaar - 2007
|
bgneal@1
|
83 - Veracity - 2011
|
bgneal@1
|
84
|
bgneal@1
|
85 ----
|
bgneal@1
|
86
|
bgneal@1
|
87 What is a CVCS Again?
|
bgneal@1
|
88 =====================
|
bgneal@1
|
89
|
bgneal@1
|
90 .. image:: images/cvcs.png
|
bgneal@1
|
91
|
bgneal@1
|
92 ----
|
bgneal@1
|
93
|
bgneal@2
|
94 So what's a DVCS look like?
|
bgneal@2
|
95 ===========================
|
bgneal@2
|
96
|
bgneal@2
|
97 .. image:: images/dvcs.png
|
bgneal@2
|
98
|
bgneal@2
|
99 All repositories are peers. By convention only, one repository is designated the master.
|
bgneal@6
|
100 It is possible for all peers to exchange changes (via *push* and *pull* operations).
|
bgneal@2
|
101
|
bgneal@2
|
102 ----
|
bgneal@2
|
103
|
bgneal@2
|
104 What does a DVCS buy you?
|
bgneal@2
|
105 =========================
|
bgneal@2
|
106
|
bgneal@2
|
107 - Private workspaces
|
bgneal@2
|
108 - Offline mode
|
bgneal@2
|
109 - Speed
|
bgneal@2
|
110 - Scalability
|
bgneal@2
|
111 - Split Geography
|
bgneal@2
|
112 - Flexible workflows
|
bgneal@2
|
113 - Distributed backups
|
bgneal@2
|
114 - **Easier merging**
|
bgneal@2
|
115 - **Commit before merge**
|
bgneal@2
|
116
|
bgneal@2
|
117 ----
|
bgneal@2
|
118
|
bgneal@2
|
119 Private Workspaces
|
bgneal@2
|
120 ==================
|
bgneal@2
|
121
|
bgneal@2
|
122 - You can safely experiment in your local repository
|
bgneal@2
|
123 - Commit as often as you like without affecting the team
|
bgneal@2
|
124 - Encourages experimentation
|
bgneal@2
|
125
|
bgneal@2
|
126 - Make cheap repository clones to try things out
|
bgneal@2
|
127 - Not visible to coworkers
|
bgneal@2
|
128
|
bgneal@2
|
129 ----
|
bgneal@2
|
130
|
bgneal@2
|
131 Offline Mode
|
bgneal@2
|
132 ============
|
bgneal@2
|
133
|
bgneal@2
|
134 - Work when you have spotty or no network access
|
bgneal@2
|
135 - Full access to the repo when offline
|
bgneal@2
|
136 - Can work on multiple tasks offline
|
bgneal@2
|
137
|
bgneal@2
|
138 - Work on bug report #1
|
bgneal@2
|
139 - Commit
|
bgneal@2
|
140 - Work on bug report #2
|
bgneal@2
|
141 - With a CVCS, you'd have both fixes in the same pending commit
|
bgneal@2
|
142
|
bgneal@2
|
143 ----
|
bgneal@2
|
144
|
bgneal@2
|
145 Speed
|
bgneal@2
|
146 =====
|
bgneal@2
|
147
|
bgneal@2
|
148 - Local operations are **fast**
|
bgneal@8
|
149
|
bgneal@8
|
150 - No, really, **you will** notice a big difference
|
bgneal@8
|
151 - Switching between branches will blow your mind
|
bgneal@8
|
152
|
bgneal@2
|
153 - Initial pull down of an entire repository *might* be slower than a CVCS
|
bgneal@2
|
154
|
bgneal@2
|
155 - Then again, you might be surprised
|
bgneal@2
|
156 - Mercurial, for example, stores an entire repository in less space than
|
bgneal@2
|
157 a SVN working copy in many cases
|
bgneal@8
|
158
|
bgneal@2
|
159
|
bgneal@2
|
160 ----
|
bgneal@2
|
161
|
bgneal@2
|
162 Scalability
|
bgneal@2
|
163 ===========
|
bgneal@2
|
164
|
bgneal@2
|
165 - Some CVCS systems require heavy weight hardware to support the server
|
bgneal@2
|
166
|
bgneal@2
|
167 - E.g. ClearCase with a thousand users
|
bgneal@2
|
168 - With a DVCS, only pushes & pulls contact a central server
|
bgneal@2
|
169 - Most of the work is done locally
|
bgneal@2
|
170
|
bgneal@2
|
171 ----
|
bgneal@2
|
172
|
bgneal@2
|
173 Split Geography
|
bgneal@2
|
174 ===============
|
bgneal@2
|
175
|
bgneal@6
|
176 - Imagine a team split between Cedar Rapids & Richardson...
|
bgneal@2
|
177 - With a CVS, you have to pick where to put the server
|
bgneal@2
|
178 - The remote location is stuck with network latency & associated problems
|
bgneal@2
|
179 - With a DVCS, each site can have a central repository
|
bgneal@2
|
180
|
bgneal@2
|
181 - The two central repos can be synched when convenient or even scripted
|
bgneal@2
|
182
|
bgneal@9
|
183 .. image:: images/split_geography.png
|
bgneal@9
|
184
|
bgneal@2
|
185 ----
|
bgneal@2
|
186
|
bgneal@2
|
187 Flexible Workflows
|
bgneal@2
|
188 ==================
|
bgneal@2
|
189
|
bgneal@2
|
190 - There is no internal concept of a central repository
|
bgneal@2
|
191 - A central repository exits only by convention
|
bgneal@2
|
192 - More elaborate topologies and workflows can be created:
|
bgneal@2
|
193
|
bgneal@2
|
194 - A SW team may push to a central SW repo
|
bgneal@2
|
195 - Periodically changes from the SW repo are pushed to a QA repo
|
bgneal@2
|
196 - Changes from the QA repo can be pushed into a release repo
|
bgneal@9
|
197
|
bgneal@9
|
198 .. image:: images/flexible_workflows.png
|
bgneal@2
|
199
|
bgneal@2
|
200 ----
|
bgneal@2
|
201
|
bgneal@2
|
202 Distributed Backups
|
bgneal@2
|
203 ===================
|
bgneal@2
|
204
|
bgneal@2
|
205 - With a DVCS, multiple copies of the repository exist on multiple machines
|
bgneal@2
|
206 - **Of course, this is no substitute for a real backup strategy!**
|
bgneal@2
|
207 - But usually, and with short notice, you can easily designate a repository as
|
bgneal@2
|
208 the central repository in an emergency
|
bgneal@2
|
209
|
bgneal@2
|
210 ----
|
bgneal@2
|
211
|
bgneal@2
|
212 Easier Merging
|
bgneal@2
|
213 ==============
|
bgneal@2
|
214
|
bgneal@2
|
215 - Subversion has a bad reputation for merging
|
bgneal@2
|
216
|
bgneal@2
|
217 - Some of this is not warranted...
|
bgneal@2
|
218
|
bgneal@2
|
219 - Merge tracking was added in SVN v1.5
|
bgneal@2
|
220
|
bgneal@2
|
221 - SVN does not handle file renames and tree conflicts very well
|
bgneal@2
|
222 - A lot of teams simply avoid merging out of fear
|
bgneal@2
|
223
|
bgneal@2
|
224 ----
|
bgneal@2
|
225
|
bgneal@2
|
226 Easier Merging (cont.)
|
bgneal@2
|
227 ======================
|
bgneal@2
|
228
|
bgneal@2
|
229 - Why is merging better in a DVCS?
|
bgneal@2
|
230
|
bgneal@2
|
231 - Merging simply has to work correctly and be easy in a DVCS
|
bgneal@2
|
232
|
bgneal@2
|
233 - More attention was paid to this aspect by DVCS's
|
bgneal@2
|
234
|
bgneal@2
|
235 - DVCS's use directed acyclic graphs internally to represent change sets
|
bgneal@2
|
236
|
bgneal@2
|
237 - More information is available to make merge decisions
|
bgneal@2
|
238 - Easier to find common ancestors of code
|
bgneal@2
|
239
|
bgneal@2
|
240 - Developer changes and merge changes are separate
|
bgneal@2
|
241
|
bgneal@2
|
242 - "Commit before merge"
|
bgneal@2
|
243
|
bgneal@2
|
244 ----
|
bgneal@2
|
245
|
bgneal@2
|
246 Commit Before Merge
|
bgneal@2
|
247 ===================
|
bgneal@2
|
248
|
bgneal@2
|
249 - With a CVCS:
|
bgneal@2
|
250
|
bgneal@2
|
251 - You make changes in your working copy
|
bgneal@2
|
252 - Before you can commit, you often must peform an update
|
bgneal@2
|
253
|
bgneal@2
|
254 - This may trigger a merge
|
bgneal@2
|
255 - Your changes are now mixed up with your friendly coworkers' changes
|
bgneal@2
|
256 - Sometimes this can be a problem...
|
bgneal@2
|
257
|
bgneal@2
|
258 - With a DVCS:
|
bgneal@2
|
259
|
bgneal@2
|
260 - You make changes in your working copy
|
bgneal@3
|
261 - You commit locally!
|
bgneal@2
|
262 - You can then choose to pull changes from others and merge
|
bgneal@2
|
263
|
bgneal@2
|
264 - **Your changes are already safely tucked away and can be retrieved later if things go wrong**
|
bgneal@2
|
265
|
bgneal@2
|
266 ----
|
bgneal@2
|
267
|
bgneal@2
|
268 Okay, what's the catch?
|
bgneal@2
|
269 =======================
|
bgneal@2
|
270
|
bgneal@2
|
271 Potential drawbacks to a DVCS
|
bgneal@2
|
272 -----------------------------
|
bgneal@2
|
273
|
bgneal@2
|
274 - Practically no support for locks
|
bgneal@2
|
275
|
bgneal@2
|
276 - This makes working with binary files difficult in a team environment
|
bgneal@2
|
277
|
bgneal@2
|
278 - Huge repositories are not practical
|
bgneal@2
|
279
|
bgneal@2
|
280 - Hetrogenous repositories are not practical
|
bgneal@2
|
281
|
bgneal@2
|
282 - Not a good idea to mix, say, software, systems, and firmware in the same repo
|
bgneal@2
|
283 - Not a good idea to mix multiple products in the same repo
|
bgneal@2
|
284 - Arguably, this applies to a CVCS as well
|
bgneal@2
|
285
|
bgneal@7
|
286 - No support for path-based access control
|
bgneal@7
|
287
|
bgneal@7
|
288 - With current tools, you either can access the full repo, or nothing
|
bgneal@7
|
289
|
bgneal@2
|
290 ----
|
bgneal@2
|
291
|
bgneal@2
|
292 Introduction to Mercurial
|
bgneal@2
|
293 =========================
|
bgneal@2
|
294
|
bgneal@5
|
295 - Overview
|
bgneal@6
|
296 - Repositories & working directories
|
bgneal@2
|
297 - Changesets
|
bgneal@4
|
298 - Branches & Tags
|
bgneal@4
|
299 - Example workflow
|
bgneal@3
|
300 - Command overview
|
bgneal@2
|
301
|
bgneal@2
|
302 ----
|
bgneal@2
|
303
|
bgneal@5
|
304 Mercurial Overview
|
bgneal@5
|
305 ==================
|
bgneal@5
|
306
|
bgneal@5
|
307 - Distributed Version Control System
|
bgneal@5
|
308 - Free, open source software licensed under GPL Version 2
|
bgneal@5
|
309 - Available for Microsoft Windows, GNU/Linux, Mac OS X, Solaris 11 Express
|
bgneal@5
|
310 - Written in Python with a small amount of C
|
bgneal@5
|
311 - Extensible with official and 3rd party extensions
|
bgneal@5
|
312 - TortoiseHg is a popular GUI for Windows
|
bgneal@5
|
313 - Reputation for being fast & easy to get started with
|
bgneal@5
|
314 - Can be served via Apache Web server
|
bgneal@5
|
315 - Repository hooks
|
bgneal@5
|
316 - Integrates with Trac
|
bgneal@5
|
317 - Can import history from other tools, including Subversion
|
bgneal@5
|
318
|
bgneal@5
|
319 ----
|
bgneal@5
|
320
|
bgneal@6
|
321 Repositories & Working Directories
|
bgneal@6
|
322 ==================================
|
bgneal@3
|
323
|
bgneal@3
|
324 A repository consists of two things:
|
bgneal@3
|
325
|
bgneal@4
|
326 - Your working directory (similar to a working copy in SVN)
|
bgneal@3
|
327 - The repository itself (also known as "the store")
|
bgneal@3
|
328
|
bgneal@3
|
329 - A .hg directory at the top of your working copy
|
bgneal@3
|
330
|
bgneal@3
|
331 Example::
|
bgneal@3
|
332
|
bgneal@4
|
333 $ ls -A
|
bgneal@3
|
334 .hg .hgignore images/ slides.cfg slides.css slides.html slides.rst
|
bgneal@3
|
335
|
bgneal@6
|
336 - Repositories communicate via the *push* and *pull* commands
|
bgneal@6
|
337
|
bgneal@6
|
338 - Push & Pull do not affect your working directory
|
bgneal@6
|
339
|
bgneal@6
|
340 - An *update* or *merge* must be performed to receive remote changes into your working directory
|
bgneal@6
|
341
|
bgneal@3
|
342 ----
|
bgneal@3
|
343
|
bgneal@3
|
344 What's in a Repository?
|
bgneal@3
|
345 =======================
|
bgneal@3
|
346
|
bgneal@3
|
347 A repository consists of a directed, acyclic graph of *changesets*
|
bgneal@3
|
348
|
bgneal@3
|
349 .. image:: images/repos.png
|
bgneal@3
|
350
|
bgneal@4
|
351 - Each changeset can have 0, 1, or 2 parents (and infinite children)
|
bgneal@3
|
352 - A changeset with 0 parents is the root
|
bgneal@3
|
353 - A changeset with 2 parents is the result of a merge
|
bgneal@4
|
354 - The newest changeset is called the *tip*, a special tag name
|
bgneal@4
|
355
|
bgneal@4
|
356 ----
|
bgneal@4
|
357
|
bgneal@4
|
358 What's a Changeset?
|
bgneal@4
|
359 ===================
|
bgneal@4
|
360
|
bgneal@4
|
361 A changeset is an atomic collection of changes and some meta information.
|
bgneal@4
|
362 The meta information includes:
|
bgneal@4
|
363
|
bgneal@4
|
364 - Who made the changes
|
bgneal@4
|
365 - When the changes were made
|
bgneal@4
|
366 - Why - the commit message
|
bgneal@4
|
367 - The name of the branch the changes were made on ("default" is the default)
|
bgneal@4
|
368 - A local revision number
|
bgneal@4
|
369 - A changeset ID; a 40 digit hex number (SHA-1 hash of the changeset & parents)
|
bgneal@4
|
370
|
bgneal@4
|
371 A changeset can be named by:
|
bgneal@4
|
372
|
bgneal@4
|
373 - Revision number (within a repository)
|
bgneal@4
|
374 - Changeset ID (globally)
|
bgneal@4
|
375 - Tag name
|
bgneal@4
|
376
|
bgneal@4
|
377 ----
|
bgneal@4
|
378
|
bgneal@4
|
379 Branches & Tags
|
bgneal@4
|
380 ===============
|
bgneal@4
|
381
|
bgneal@4
|
382 - In the simple case, each changeset appear in a line
|
bgneal@4
|
383 - When a changeset develops 2 or more children, a branch occurs
|
bgneal@4
|
384
|
bgneal@4
|
385 - The latest revision of a branch is called a *head*
|
bgneal@4
|
386 - A *merge* is when two branches join back together
|
bgneal@4
|
387 - Branches can be given names; the default branch name is *"default"*
|
bgneal@4
|
388
|
bgneal@4
|
389 - Changesets can be given human readable names, or *tags*
|
bgneal@4
|
390
|
bgneal@4
|
391 - *Local tags* are only visible within a repository
|
bgneal@4
|
392 - *Regular tags* are revision controlled and propagate to other repos
|
bgneal@4
|
393 - The newest head in a repository is a tag called *tip*
|
bgneal@4
|
394
|
bgneal@4
|
395 ----
|
bgneal@4
|
396
|
bgneal@4
|
397 Example Workflow
|
bgneal@4
|
398 ================
|
bgneal@4
|
399
|
bgneal@4
|
400 .. image:: images/workflow1.png
|
bgneal@4
|
401
|
bgneal@4
|
402 ----
|
bgneal@4
|
403
|
bgneal@4
|
404 Example Workflow (cont.)
|
bgneal@4
|
405 ========================
|
bgneal@4
|
406
|
bgneal@4
|
407 .. image:: images/workflow2.png
|
bgneal@4
|
408
|
bgneal@4
|
409 ----
|
bgneal@4
|
410
|
bgneal@4
|
411 Example Workflow (cont.)
|
bgneal@4
|
412 ========================
|
bgneal@4
|
413
|
bgneal@4
|
414 .. image:: images/workflow3.png
|
bgneal@3
|
415
|
bgneal@6
|
416 - Notice that after Alice's pull:
|
bgneal@6
|
417
|
bgneal@6
|
418 - Her working directory is unaffected
|
bgneal@6
|
419 - Her repository only has one head => no merging required
|
bgneal@6
|
420
|
bgneal@6
|
421
|
bgneal@3
|
422 ----
|
bgneal@3
|
423
|
bgneal@3
|
424 SVN Commands for Review
|
bgneal@3
|
425 =======================
|
bgneal@1
|
426
|
bgneal@1
|
427 Basic SVN commands:
|
bgneal@1
|
428
|
bgneal@1
|
429 - add, remove, copy, move, mkdir
|
bgneal@1
|
430 - checkout, commit, update, revert
|
bgneal@1
|
431 - merge, resolved, diff
|
bgneal@4
|
432 - status, log
|
bgneal@1
|
433 - lock, unlock
|
bgneal@1
|
434
|
bgneal@1
|
435 ----
|
bgneal@1
|
436
|
bgneal@4
|
437 Basic Mercurial Commands
|
bgneal@4
|
438 ========================
|
bgneal@1
|
439
|
bgneal@1
|
440 Mercurial (hg) vs SVN commands:
|
bgneal@1
|
441
|
bgneal@1
|
442 - add, remove, copy, move, :strike:`mkdir`
|
bgneal@1
|
443 - :strike:`checkout`, commit, update, revert
|
bgneal@4
|
444 - merge, resolve, diff, **heads**
|
bgneal@4
|
445 - status, log
|
bgneal@1
|
446 - :strike:`lock, unlock`
|
bgneal@1
|
447
|
bgneal@1
|
448 Additional "distributed commands":
|
bgneal@1
|
449
|
bgneal@5
|
450 - **clone**, **push**, **pull**
|
bgneal@5
|
451 - **incoming**, **outgoing**
|
bgneal@1
|
452
|
bgneal@4
|
453 **Not a whole lot to learn above SVN**
|
bgneal@4
|
454
|
bgneal@4
|
455 ----
|
bgneal@4
|
456
|
bgneal@4
|
457 References
|
bgneal@4
|
458 ==========
|
bgneal@4
|
459
|
bgneal@4
|
460 - Mercurial http://mercurial.selenic.com/
|
bgneal@4
|
461 - Mercurial Wiki http://mercurial.selenic.com/wiki/
|
bgneal@4
|
462 - Mercurial Book (free!) http://hgbook.red-bean.com/
|
bgneal@4
|
463 - Hg Init: A Mercurial Tutorial http://hginit.com
|
bgneal@4
|
464 - Version Control By Example (free!) http://www.ericsink.com/vcbe/
|
bgneal@4
|
465
|
bgneal@5
|
466 This presentation is available at::
|
bgneal@5
|
467
|
bgneal@5
|
468 $ hg clone https://bitbucket.org/bgneal/dvcs_intro_brownbag
|
bgneal@5
|
469
|
bgneal@4
|
470 ----
|
bgneal@4
|
471
|
bgneal@4
|
472 Questions?
|
bgneal@4
|
473 ==========
|
bgneal@4
|
474
|