188 obsolete in ``test-repo``, having been replaced by revision 3:60ff |
188 obsolete in ``test-repo``, having been replaced by revision 3:60ff |
189 (revision 2:2a03 is another one of those temporary amend commits that |
189 (revision 2:2a03 is another one of those temporary amend commits that |
190 we saw in the user guide)—but ``dev-repo`` knows nothing of these |
190 we saw in the user guide)—but ``dev-repo`` knows nothing of these |
191 recent developments. |
191 recent developments. |
192 |
192 |
193 [figure SG02: rev 0:0dc9 public, rev 1:f649, 2:2a03 obsolete, rev 3:60ff draft -- but dev-repo same as in SG01] |
193 [figure SG02: test-repo has rev 0:0dc9 public, rev 1:f649, 2:2a03 obsolete, rev 3:60ff draft; dev-repo same as in SG01] |
194 |
194 |
195 Let's resynchronize:: |
195 Let's resynchronize:: |
196 |
196 |
197 $ cd ../dev-repo |
197 $ cd ../dev-repo |
198 $ hg pull -u |
198 $ hg pull -u |
|
199 [...] |
|
200 added 1 changesets with 1 changes to 1 files (+1 heads) |
|
201 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
199 |
202 |
200 As seen in figure 3, this transfers the new changeset *and* the |
203 As seen in figure 3, this transfers the new changeset *and* the |
201 obsolescence marker for revision 1. However, it does *not* transfer |
204 obsolescence marker for revision 1. However, it does *not* transfer |
202 the temporary amend commit, because it is obsolete. Push and pull |
205 the temporary amend commit, because it is hidden. Push and pull |
203 transfer obsolesence markers between repositories, but they do not |
206 transfer obsolesence markers between repositories, but they do not |
204 normally transfer obsolete changesets. |
207 transfer hidden changesets. |
205 |
208 |
206 [figure SG03: dev-repo grows new rev 2:60ff, marks 1:f649 obsolete] |
209 [figure SG03: dev-repo grows new rev 2:60ff, marks 1:f649 obsolete] |
207 |
210 |
208 Because of this deliberately incomplete synchronization, revision |
211 Because of this deliberately incomplete synchronization, revision |
209 numbers in ``test-repo`` and ``dev-repo`` are no longer consistent. We |
212 numbers in ``test-repo`` and ``dev-repo`` are no longer consistent. We |
264 public. Let's avoid that situation for now by pulling from |
264 public. Let's avoid that situation for now by pulling from |
265 ``test-repo`` down to ``dev-repo``:: |
265 ``test-repo`` down to ``dev-repo``:: |
266 |
266 |
267 $ cd ../dev-repo |
267 $ cd ../dev-repo |
268 $ hg pull -u |
268 $ hg pull -u |
269 |
269 [...] |
270 Sharing with multiple developers |
270 no changes found |
271 -------------------------------- |
271 |
|
272 Even though no *changesets* were pulled, Mercurial still pulled |
|
273 obsolescence markers from ``test-repo``. |
|
274 |
|
275 Sharing with multiple developers: code review |
|
276 --------------------------------------------- |
|
277 |
|
278 Now that you know how to share your own mutable history across |
|
279 multiple computers, you might be wondering if it makes sense to share |
|
280 mutable history with others. It does, but you have to be careful, stay |
|
281 alert, and *communicate* with your peers. |
|
282 |
|
283 A good way to start is with code review: Alice commits a draft |
|
284 changeset that Bob can review. Bob sends his comments to Alice, and |
|
285 she amends it until Bob is satisfied. Meanwhile, Bob is also |
|
286 committing draft changesets for Alice to review, amending until she is |
|
287 satisfied. Once a particular changeset passes review, the respective |
|
288 author (Alice or Bob) pushes it to the public repository. |
|
289 |
|
290 Setting up |
|
291 ========== |
|
292 |
|
293 To demonstrate, let's start with the ``public`` repository as we left |
|
294 it in the last example, with two immutable changesets (figure 5 |
|
295 above). We'll clone a ``review`` repository from it, and then Alice |
|
296 and Bob will both clone from ``review``. :: |
|
297 |
|
298 $ hg clone public review |
|
299 updating to branch default |
|
300 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
301 $ hg clone review alice |
|
302 updating to branch default |
|
303 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
304 $ hg clone review bob |
|
305 updating to branch default |
|
306 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
307 |
|
308 We need to configure Alice's and Bob's working repositories similar to |
|
309 ``test-repo``, i.e. make them non-publishing and enable ``evolve``. |
|
310 First, edit Alice's configuration with :: |
|
311 |
|
312 $ hg -R alice config --edit --local |
|
313 |
|
314 and add :: |
|
315 |
|
316 [extensions] |
|
317 evolve = /path/to/mutable-history/hgext/evolve.py |
|
318 |
|
319 Then add the same text to Bob's repository configuration:: |
|
320 |
|
321 $ hg -R bob config --edit --local |
|
322 |
|
323 Example 3: Alice commits and amends a draft fix |
|
324 =============================================== |
|
325 |
|
326 We'll start by following Alice working on a bug fix. We're going to |
|
327 use bookmarks to make it easier to understand multiple branch heads in |
|
328 the ``review`` repository, so Alice starts off by creating a bookmark |
|
329 and committing her first attempt at a fix:: |
|
330 |
|
331 $ hg bookmark bug15 |
|
332 $ echo 'fix' > file2 |
|
333 $ hg commit -A -u alice -m 'fix bug 15 (v1)' |
|
334 adding file2 |
|
335 |
|
336 Note the unorthodox "(v1)" in the commit message. We're just using |
|
337 that to make this tutorial easier to follow; it's not something we'd |
|
338 recommend in real life. |
|
339 |
|
340 Of course Alice wouldn't commit unless her fix worked to her |
|
341 satisfaction, so it must be time to solicit a code review. She does |
|
342 this by pushing to the ``review`` repository:: |
|
343 |
|
344 $ hg push -B bug15 |
|
345 [...] |
|
346 added 1 changesets with 1 changes to 1 files |
|
347 exporting bookmark bug15 |
|
348 |
|
349 (The use of ``-B`` is important to ensure that we only push the |
|
350 bookmarked head, and that the bookmark itself is pushed. See this |
|
351 `guide to bookmarks`_, especially the `Sharing Bookmarks`_ section, if |
|
352 you're not familiar with bookmarks.) |
|
353 |
|
354 .. _`guide to bookmarks`: http://mercurial.aragost.com/kick-start/en/bookmarks/ |
|
355 .. _`Sharing Bookmarks`: http://mercurial.aragost.com/kick-start/en/bookmarks/#sharing-bookmarks |
|
356 |
|
357 Some time passes, and Alice receives her code review. (It might be by |
|
358 email, telephone, or carrier pigeon: it doesn't matter, as it's |
|
359 outside the scope of Mercurial.) As a result, Alice revises her fix |
|
360 and submits it for a second review:: |
|
361 |
|
362 $ echo 'Fix.' > file2 |
|
363 $ hg amend -m 'fix bug 15 (v2)' |
|
364 $ hg push |
|
365 [...] |
|
366 added 1 changesets with 1 changes to 1 files (+1 heads) |
|
367 updating bookmark bug15 |
|
368 |
|
369 Figure 6 shows the state of the ``review`` repository at this point. |
|
370 |
|
371 [figure SG06: rev 2:fn1e is alice's obsolete v1, rev 3:cbdf is her v2; both children of rev 1:de61] |
|
372 |
|
373 After a hard morning of bug fixing, Alice stops for lunch. Let's see |
|
374 what Bob has been up to. |
|
375 |
|
376 Example 4: Bob implements and publishes a new feature |
|
377 ===================================================== |
|
378 |
|
379 In the meantime, Bob has been working on a new feature. Like Alice, |
|
380 he'll use a bookmark to track his work, and he'll push that bookmark |
|
381 to the ``review`` repository, so that reviewers know which changesets |
|
382 to review. :: |
|
383 |
|
384 $ cd ../bob |
|
385 $ echo 'stuff' > file1 |
|
386 $ hg bookmark featureX |
|
387 $ hg commit -u bob -m 'implement feature X (v1)' |
|
388 $ hg push -B featureX |
|
389 [...] |
|
390 added 1 changesets with 1 changes to 1 files (+1 heads) |
|
391 exporting bookmark featureX |
|
392 |
|
393 When Bob receives his code review, he improves his implementation a |
|
394 bit, amends, and submits the resulting changeset for review:: |
|
395 |
|
396 $ echo 'do stuff' > file1 |
|
397 $ hg amend -m 'implement feature X (v2)' |
|
398 $ hg push |
|
399 [...] |
|
400 added 1 changesets with 1 changes to 1 files (+1 heads) |
|
401 updating bookmark featureX |
|
402 |
|
403 Unfortunately, that still doesn't pass muster. Bob's reviewer insists |
|
404 on proper capitalization and punctuation. :: |
|
405 |
|
406 $ echo 'Do stuff.' > file1 |
|
407 $ hg amend -m 'implement feature X (v3)' |
|
408 |
|
409 On the bright side, the second review said, "Go ahead and publish once |
|
410 you fix that." So Bob immediately publishes his third attempt:: |
|
411 |
|
412 $ hg push ../public |
|
413 [...] |
|
414 added 1 changesets with 1 changes to 1 files |
|
415 |
|
416 Bob also has to update the ``review`` repository: right now it doesn't |
|
417 have his latest amendment ("v3", revision 6:540b), and it doesn't know |
|
418 that the precursor of that changeset ("v2", revision 5:0eb7) is |
|
419 obsolete. :: |
|
420 |
|
421 $ hg push ../review |
|
422 [...] |
|
423 added 1 changesets with 1 changes to 1 files (+1 heads) |
|
424 updating bookmark featureX |
|
425 |
|
426 Figure 7 shows the result of Bob's work in both ``review`` and |
|
427 ``public``. |
|
428 |
|
429 [figure SG07: review includes alice's draft work on bug 15, as well as Bob's v1, v2, and v3 changes for feature X: v1 and v2 obsolete, v3 public. public contains only the final, public implementation of feature X] |
|
430 |
|
431 Incidentally, it's important that Bob push to ``public`` *before* |
|
432 ``review``. If he pushed to ``review`` first, then revision 6:540b |
|
433 would still be in *draft* phase in ``review``, but it would be |
|
434 *public* in both Bob's local repository and the ``public`` repository. |
|
435 That could lead to confusion at some point, which is easily avoided by |
|
436 pushing first to ``public``. |
|
437 |
|
438 Example 5: Alice integrates and publishes |
|
439 ========================================= |
|
440 |
|
441 Finally, Alice gets back from lunch and sees that the carrier pigeon |
|
442 with her second review has arrived (or maybe she just has it in her |
|
443 email inbox). Alice's amended changeset has passed review, so she |
|
444 pushes her fix to ``public``:: |
|
445 |
|
446 $ hg push ../public |
|
447 [...] |
|
448 remote has heads on branch 'default' that are not known locally: 540ba8f317e6 |
|
449 abort: push creates new remote head cbdfbd5a5db2! |
|
450 (pull and merge or see "hg help push" for details about pushing new heads) |
|
451 |
|
452 Oops! Bob has won the race to push first to ``public``. So Alice needs |
|
453 to integrate with Bob: let's pull his changeset(s) and see what the |
|
454 branch heads are. :: |
|
455 |
|
456 $ hg pull ../public |
|
457 [...] |
|
458 added 1 changesets with 1 changes to 1 files (+1 heads) |
|
459 (run 'hg heads' to see heads, 'hg merge' to merge) |
|
460 $ hg log -G -q -r 'head()' --template '{rev}:{node|short} ({author})\n' |
|
461 o 5:540ba8f317e6 (bob) |
|
462 | |
|
463 | @ 4:cbdfbd5a5db2 (alice) |
|
464 |/ |
|
465 |
|
466 Since Alice and Bob are already using advanced technology in the form |
|
467 of shared mutable history, we'll assume they are perfectly comfortable |
|
468 with rebasing changesets. So Alice rebases her changeset on top of |
|
469 Bob's and publishes the result:: |
|
470 |
|
471 $ hg rebase -d 5 |
|
472 $ hg push ../public |
|
473 [...] |
|
474 added 1 changesets with 1 changes to 1 files |
|
475 $ hg push ../review |
|
476 [...] |
|
477 added 1 changesets with 0 changes to 0 files |
|
478 updating bookmark bug15 |
|
479 |
|
480 The result, in both ``review`` and ``public`` repositories, is shown |
|
481 in figure 8. |
|
482 |
|
483 [figure SG08: review shows v1 and v2 of alice's fix, then v1, v2, v3 of bob's feature, finally alice's fix rebased onto bob's. public just shows the final public version of each changeset] |
|
484 |
|
485 |
|
486 ** STOP HERE: WORK IN PROGRESS ** |
|
487 |
|
488 |
|
489 Getting into trouble with shared mutable history |
|
490 ------------------------------------------------ |
272 |
491 |
273 Mercurial with ``evolve`` is a powerful tool, and using powerful tools |
492 Mercurial with ``evolve`` is a powerful tool, and using powerful tools |
274 can have consequences. (You can cut yourself badly with a sharp knife, |
493 can have consequences. (You can cut yourself badly with a sharp knife, |
275 but every competent chef keeps several around. Ever try to chop onions |
494 but every competent chef keeps several around. Ever try to chop onions |
276 with a spoon?) |
495 with a spoon?) |