comparison docs/tutorials/tutorial.t @ 163:92b073d13f2d

more doc update
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Wed, 21 Mar 2012 19:09:24 +0100
parents
children 7bee48a54c4a
comparison
equal deleted inserted replaced
162:1a6ae8d8f104 163:92b073d13f2d
1 Mutable History and collaboration
2 =====================================================================
3
4
5 .. warning:: need heavy update
6
7
8 Single Developer Usage
9 ======================
10
11 This tutorial shows how to use evolution to replace the basics of *mq*.
12
13
14 Amending a changeset
15 ---------------------
16
17
18 First there is some setup phase you will understand later.
19
20 there is a local repository and a remote one.
21
22 Please close your eyes.
23
24 $ hg init local
25 $ cat >> local/.hg/hgrc << EOF
26 > [paths]
27 > remote = ../remote
28 > [ui]
29 > user = Albert Beugras
30 > [diff]
31 > git = 1
32 > [alias]
33 > amend = amend -d '0 0'
34 > tlog = log --template "{node|short}: '{desc}'\n"
35 > ttlog = log --template "{node|short}: '{desc}' ({state})\n"
36 > tglog = log -G --template "{node|short}: '{desc}' {branches}\n"
37 > [extensions]
38 > hgext.graphlog=
39 > hgext.rebase=
40 > EOF
41 $ echo "states=$(echo $(dirname $TESTDIR))/hgext/states.py" >> local/.hg/hgrc
42 $ echo "obsolete=$(echo $(dirname $TESTDIR))/hgext/obsolete.py" >> local/.hg/hgrc
43 $ echo "evolution=$(echo $(dirname $TESTDIR))/hgext/evolution.py" >> local/.hg/hgrc
44 $ hg init remote
45 $ cat >> remote/.hg/hgrc << EOF
46 > [paths]
47 > local = ../local
48 > [ui]
49 > user = René de Robert
50 > [diff]
51 > git = 1
52 > [alias]
53 > amend = amend -d '0 0'
54 > tlog = log --template "{node|short}: '{desc}' {branches}\n"
55 > ttlog = log --template "{node|short}: '{desc}' {state}\n"
56 > tglog = log -G --template "{node|short}: '{desc}' {branches}\n"
57 > [extensions]
58 > hgext.graphlog=
59 > hgext.rebase=
60 > EOF
61 $ echo "states=$(echo $(dirname $TESTDIR))/hgext/states.py" >> remote/.hg/hgrc
62 $ echo "obsolete=$(echo $(dirname $TESTDIR))/hgext/obsolete.py" >> remote/.hg/hgrc
63 $ echo "evolution=$(echo $(dirname $TESTDIR))/hgext/evolution.py" >> remote/.hg/hgrc
64 $ cd local
65
66 You can reopen you eyes.
67
68 Now we make a first version of our shopping list.
69
70 $ cat >> shopping << EOF
71 > Spam
72 > Whizzo butter
73 > Albatross
74 > Rat (rather a lot)
75 > Jugged fish
76 > Blancmange
77 > Salmon mousse
78 > EOF
79 $ hg commit -A -m "Monthy Python Shopping list"
80 adding shopping
81
82 We share this first version with the outside.
83
84 $ hg push remote
85 pushing to $TESTTMP/remote
86 searching for changes
87 adding changesets
88 adding manifests
89 adding file changes
90 added 1 changesets with 1 changes to 1 files
91
92 Later I add additional item to my list
93
94 $ cat >> shopping << EOF
95 > Egg
96 > Suggar
97 > Vinegar
98 > Oil
99 > EOF
100 $ hg commit -m "adding condiment"
101 $ cat >> shopping << EOF
102 > Bananos
103 > Pear
104 > Apple
105 > EOF
106 $ hg commit -m "adding fruit"
107
108 I now have the following history:
109
110 $ hg tlog
111 d85de4546133: 'adding fruit'
112 4d5dc8187023: 'adding condiment'
113 7e82d3f3c2cb: 'Monthy Python Shopping list'
114
115 But, I just notice, I made a typo in Banana.
116
117 $ hg export tip
118 # HG changeset patch
119 # User test
120 # Date 0 0
121 # Node ID d85de4546133030c82d257bbcdd9b1b416d0c31c
122 # Parent 4d5dc81870237d492284826e21840b2ca00e26d1
123 adding fruit
124
125 diff --git a/shopping b/shopping
126 --- a/shopping
127 +++ b/shopping
128 @@ -9,3 +9,6 @@
129 Suggar
130 Vinegar
131 Oil
132 +Bananos
133 +Pear
134 +Apple
135
136 hopefully. I can use hg amend to rewrite my faulty changeset!
137
138 $ sed -i'' -e s/Bananos/Banana/ shopping
139 $ hg diff
140 diff --git a/shopping b/shopping
141 --- a/shopping
142 +++ b/shopping
143 @@ -9,6 +9,6 @@
144 Suggar
145 Vinegar
146 Oil
147 -Bananos
148 +Banana
149 Pear
150 Apple
151 $ hg amend
152 abort: can not rewrite immutable changeset d85de4546133
153 [255]
154
155 By default all changeset are considered "published" and can't be rewrittent.
156
157 $ hg ttlog
158
159 You need to enable a mutable state in your repo the "ready" one
160
161 $ hg states ready --clever
162 $ hg ttlog
163 d85de4546133: 'adding fruit' (ready)
164 4d5dc8187023: 'adding condiment' (ready)
165 7e82d3f3c2cb: 'Monthy Python Shopping list' (published)
166
167 Notice that changeset you already shared with the outside have been keep
168 published.
169
170 The changeset we want to rewrite is now in a mutable state.
171
172 $ hg amend
173
174 A new changeset with the right diff replace the wrong one.
175
176 $ hg tlog
177 0cacb48f4482: 'adding fruit'
178 4d5dc8187023: 'adding condiment'
179 7e82d3f3c2cb: 'Monthy Python Shopping list'
180 $ hg export tip
181 # HG changeset patch
182 # User test
183 # Date 0 0
184 # Node ID 0cacb48f44828d2fd31c4e45e18fde32a5b2f07b
185 # Parent 4d5dc81870237d492284826e21840b2ca00e26d1
186 adding fruit
187
188 diff --git a/shopping b/shopping
189 --- a/shopping
190 +++ b/shopping
191 @@ -9,3 +9,6 @@
192 Suggar
193 Vinegar
194 Oil
195 +Banana
196 +Pear
197 +Apple
198
199 Getting Ride of branchy history
200 ----------------------------------
201
202 While I was working on my list. someone help made a change remotly.
203
204 close your eyes
205
206 $ cd ../remote
207 $ hg up -q
208 $ sed -i'' -e 's/Spam/Spam Spam Spam/' shopping
209 $ hg ci -m 'SPAM'
210 $ cd ../local
211
212 open your eyes
213
214 $ hg pull remote
215 pulling from $TESTTMP/remote
216 searching for changes
217 adding changesets
218 adding manifests
219 adding file changes
220 added 1 changesets with 1 changes to 1 files (+1 heads)
221 (run 'hg heads .' to see heads, 'hg merge' to merge)
222
223 I now have a new heads. Note that the remote head is immutable
224
225 $ hg ttlog
226 9ca060c80d74: 'SPAM' (published)
227 0cacb48f4482: 'adding fruit' (ready)
228 4d5dc8187023: 'adding condiment' (ready)
229 7e82d3f3c2cb: 'Monthy Python Shopping list' (published)
230 $ hg tglog -r "::(9ca060c80d74 + 0cacb48f4482)"
231 o 9ca060c80d74: 'SPAM'
232 |
233 | @ 0cacb48f4482: 'adding fruit'
234 | |
235 | o 4d5dc8187023: 'adding condiment'
236 |/
237 o 7e82d3f3c2cb: 'Monthy Python Shopping list'
238
239
240 instead of merging my head with the new one. I'm going to rebase my work
241
242 $ hg diff
243 $ hg rebase -d 9ca060c80d74 -s 4d5dc8187023
244 merging shopping
245 merging shopping
246 merging shopping
247 merging shopping
248
249
250 My local work is now rebase on the remote one.
251
252 $ hg kill e7a71e229632 ad97bbd3e37d # XXX fix me instead
253 $ hg ttlog
254 387187ad9bd9: 'adding fruit' (ready)
255 dfd3a2d7691e: 'adding condiment' (ready)
256 9ca060c80d74: 'SPAM' (published)
257 7e82d3f3c2cb: 'Monthy Python Shopping list' (published)
258 $ hg tglog -r '::.'
259 @ 387187ad9bd9: 'adding fruit'
260 |
261 o dfd3a2d7691e: 'adding condiment'
262 |
263 o 9ca060c80d74: 'SPAM'
264 |
265 o 7e82d3f3c2cb: 'Monthy Python Shopping list'
266
267
268 Removing changeset
269 ------------------------
270
271 I add new item to my list
272
273 $ cat >> shopping << EOF
274 > car
275 > bus
276 > plane
277 > boat
278 > EOF
279 $ hg ci -m 'transport'
280 $ hg ttlog
281 d58c77aa15d7: 'transport' (ready)
282 387187ad9bd9: 'adding fruit' (ready)
283 dfd3a2d7691e: 'adding condiment' (ready)
284 9ca060c80d74: 'SPAM' (published)
285 7e82d3f3c2cb: 'Monthy Python Shopping list' (published)
286
287 I have a new commit but I realize that don't want it. (transport shop list does
288 not fit well in my standard shopping list)
289
290 $ hg kill . # . is for working directory parent.
291 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
292 working directory now at 387187ad9bd9
293
294 The silly changeset is gone.
295
296 $ hg ttlog
297 387187ad9bd9: 'adding fruit' (ready)
298 dfd3a2d7691e: 'adding condiment' (ready)
299 9ca060c80d74: 'SPAM' (published)
300 7e82d3f3c2cb: 'Monthy Python Shopping list' (published)
301
302 Reordering changeset
303 ------------------------
304
305
306 We create two changeset.
307
308
309 $ cat >> shopping << EOF
310 > Shampoo
311 > Toothbrush
312 > ... More bathroom stuff to come
313 > Towel
314 > Soap
315 > EOF
316 $ hg ci -m 'bathroom stuff' -q # XXX remove the -q
317
318 $ sed -i'' -e 's/Spam/Spam Spam Spam/g' shopping
319 $ hg ci -m 'SPAM SPAM'
320 $ hg ttlog
321 c48f32fb1787: 'SPAM SPAM' (ready)
322 8d39a843582d: 'bathroom stuff' (ready)
323 387187ad9bd9: 'adding fruit' (ready)
324 dfd3a2d7691e: 'adding condiment' (ready)
325 9ca060c80d74: 'SPAM' (published)
326 7e82d3f3c2cb: 'Monthy Python Shopping list' (published)
327
328 .. note: don't amend changeset 7e82d3f3c2cb or 9ca060c80d74 as they are
329 immutable.
330
331 I now want to push to remote all my change but the bathroom one that i'm not totally happy with yet.
332
333 To be able to push "SPAM SPAM" I need a version of "SPAM SPAM" not children of "bathroom stuff"
334
335 You can use rebase or relocate for that:
336
337 $ hg relocate 'p1(8d39a843582d)' --traceback
338 merging shopping
339 $ hg tglog -r '::(. + 8d39a843582d)'
340 @ 02e33960e937: 'SPAM SPAM'
341 |
342 | o 8d39a843582d: 'bathroom stuff'
343 |/
344 o 387187ad9bd9: 'adding fruit'
345 |
346 o dfd3a2d7691e: 'adding condiment'
347 |
348 o 9ca060c80d74: 'SPAM'
349 |
350 o 7e82d3f3c2cb: 'Monthy Python Shopping list'
351
352
353 We have a new SPAM SPAM version without the bathroom stuff
354
355 $ grep Spam shopping # enouth spamm
356 Spam Spam Spam Spam Spam Spam Spam Spam Spam
357 $ grep Toothbrush shopping # no Toothbrush
358 [1]
359 $ hg export .
360 # HG changeset patch
361 # User test
362 # Date 0 0
363 # Node ID 02e33960e937ad1bd59241ebdafd7a2494240ddf
364 # Parent 387187ad9bd9d8f9a00a9fa804a26231db547429
365 SPAM SPAM
366
367 diff --git a/shopping b/shopping
368 --- a/shopping
369 +++ b/shopping
370 @@ -1,4 +1,4 @@
371 -Spam Spam Spam
372 +Spam Spam Spam Spam Spam Spam Spam Spam Spam
373 Whizzo butter
374 Albatross
375 Rat (rather a lot)
376
377 we can now push our change:
378
379 $ hg push -r . remote
380 pushing to $TESTTMP/remote
381 searching for changes
382 adding changesets
383 adding manifests
384 adding file changes
385 added 3 changesets with 3 changes to 1 files
386
387 for simplicity shake we relocate the bathroom changeset
388
389 $ hg relocate -r 8d39a843582d 02e33960e937
390 merging shopping
391
392
393 Splitting change
394 ------------------
395
396 To be done (currently achieve with "two commit + debugobsolete")
397
398 Collapsing change
399 ------------------
400
401 To be done (currently achieve with "revert + debugobsolete" or "rebase --collapse")
402
403 collaboration
404 ====================
405
406
407 sharing mutable changeset
408 ----------------------------
409
410 To share mutable changeset with other just check that both have the "ready"
411 state activated. Otherwise you will get the previously observe behavior where
412 exchanged changeset are automatically published.
413
414 $ cd ../remote
415 $ hg states
416 published
417
418 The remote repository have only the immutable "published" state activated. Any
419 changeset echanged from "local" to "remote" will be set in the publised state:
420
421 $ hg -R ../local push -f remote # XXX we should pull but the support is awful
422 pushing to $TESTTMP/remote
423 searching for changes
424 adding changesets
425 adding manifests
426 adding file changes
427 added 1 changesets with 1 changes to 1 files
428 $ hg ttlog
429 a3515e5d0332: 'bathroom stuff' published
430 02e33960e937: 'SPAM SPAM' published
431 387187ad9bd9: 'adding fruit' published
432 dfd3a2d7691e: 'adding condiment' published
433 9ca060c80d74: 'SPAM' published
434 7e82d3f3c2cb: 'Monthy Python Shopping list' published
435
436
437
438 We do not want to publish the "bathroom changeset". Let's rollback the last transaction
439
440 $ hg rollback
441 repository tip rolled back to revision 4 (undo push)
442 working directory now based on revision 1
443 $ hg ttlog
444 02e33960e937: 'SPAM SPAM' published
445 387187ad9bd9: 'adding fruit' published
446 dfd3a2d7691e: 'adding condiment' published
447 9ca060c80d74: 'SPAM' published
448 7e82d3f3c2cb: 'Monthy Python Shopping list' published
449 $ rm ../local/.hg/states/published-heads # XXX USE --exact
450 $ hg -R ../local publish 02e33960e937 # XXX FIX THE BUG
451
452 To enable the mutable "ready" state in a repository, use the states command.
453
454 $ hg states ready
455 $ hg states
456 published
457 ready
458
459 I can nom exchange mutable changeset between "remote" and "local" repository.
460
461 $ hg pull local # XXX We pull too much stuff
462 pulling from $TESTTMP/local
463 searching for changes
464 adding changesets
465 adding manifests
466 adding file changes
467 added 10 changesets with 10 changes to 1 files (+5 heads)
468 (run 'hg heads' to see heads, 'hg merge' to merge)
469 $ hg ttlog
470 a3515e5d0332: 'bathroom stuff' ready
471 02e33960e937: 'SPAM SPAM' published
472 387187ad9bd9: 'adding fruit' published
473 dfd3a2d7691e: 'adding condiment' published
474 9ca060c80d74: 'SPAM' published
475 7e82d3f3c2cb: 'Monthy Python Shopping list' published
476
477 Rebasing out-of-sync change after update
478 ----------------------------------------------
479
480 Remotely someone add a new changeset on top of our mutable "bathroom" on.
481
482 $ hg up a3515e5d0332 -q
483 $ cat >> shopping << EOF
484 > Giraffe
485 > Rhino
486 > Lion
487 > Bear
488 > EOF
489 $ hg ci -m 'animals' -q # XXX remove the -q
490
491 While this time locally, we rebase the updated the "bathroom changeset"
492
493 $ cd ../local
494 $ hg up a3515e5d0332 -q
495 $ sed -i'' -e 's/... More bathroom stuff to come/Bath Robe/' shopping
496 $ hg amend
497 $ hg tlog
498 962d3a7d27ad: 'bathroom stuff'
499 02e33960e937: 'SPAM SPAM'
500 387187ad9bd9: 'adding fruit'
501 dfd3a2d7691e: 'adding condiment'
502 9ca060c80d74: 'SPAM'
503 7e82d3f3c2cb: 'Monthy Python Shopping list'
504
505
506 When we pull from remote again we get an unstable state!
507
508 $ hg pull remote
509 pulling from $TESTTMP/remote
510 searching for changes
511 adding changesets
512 adding manifests
513 adding file changes
514 added 1 changesets with 1 changes to 1 files (+1 heads)
515 (run 'hg heads .' to see heads, 'hg merge' to merge)
516 $ hg tlog
517 0b061760b677: 'animals'
518 962d3a7d27ad: 'bathroom stuff'
519 a3515e5d0332: 'bathroom stuff'
520 02e33960e937: 'SPAM SPAM'
521 387187ad9bd9: 'adding fruit'
522 dfd3a2d7691e: 'adding condiment'
523 9ca060c80d74: 'SPAM'
524 7e82d3f3c2cb: 'Monthy Python Shopping list'
525
526 The new changeset "animal" is based one an old changeset of "bathroom". You can
527 see both version showing up the log.
528
529 $ hg tglog -r '::(962d3a7d27ad + 0b061760b677)'
530 o 0b061760b677: 'animals'
531 |
532 | @ 962d3a7d27ad: 'bathroom stuff'
533 | |
534 o | a3515e5d0332: 'bathroom stuff'
535 |/
536 o 02e33960e937: 'SPAM SPAM'
537 |
538 o 387187ad9bd9: 'adding fruit'
539 |
540 o dfd3a2d7691e: 'adding condiment'
541 |
542 o 9ca060c80d74: 'SPAM'
543 |
544 o 7e82d3f3c2cb: 'Monthy Python Shopping list'
545
546
547 In hgviewn there is a nice doted relation highlighting 962d3a7d27ad is a new
548 version of a3515e5d0332. this is not yet ported to graphlog.
549
550 To resolve this unstable state, you need to relocate 0b061760b677 onto
551 962d3a7d27ad the "hg evolve" will make the thinking for you and suggest it to
552 you.
553
554 $ hg evolve
555 hg relocate --rev 0b061760b677 962d3a7d27ad
556
557 Let's do it
558
559 $ hg relocate --rev 0b061760b677 962d3a7d27ad
560 merging shopping
561
562 The old vesion of bathroom is hidden again now.
563
564 $ hg tlog
565 39a85a192689: 'animals'
566 962d3a7d27ad: 'bathroom stuff'
567 02e33960e937: 'SPAM SPAM'
568 387187ad9bd9: 'adding fruit'
569 dfd3a2d7691e: 'adding condiment'
570 9ca060c80d74: 'SPAM'
571 7e82d3f3c2cb: 'Monthy Python Shopping list'
572
573 We can push this evolution to remote
574
575 $ hg push -f remote # XXX should not require -f
576 pushing to $TESTTMP/remote
577 searching for changes
578 adding changesets
579 adding manifests
580 adding file changes
581 added 2 changesets with 2 changes to 1 files (+1 heads)
582
583 remote get a warning that current working directory is based on an obsolete changeset
584
585 $ cd ../remote
586 $ hg up . # XXX "loulz"
587 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
588 Working directory parent is obsolete
589
590 $ hg up 39a85a192689
591 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
592
593 Relocating out-of-sync change after kill
594 ----------------------------------------------
595
596 The remote guy keep working
597
598 $ sed -i'' -e 's/Spam/Spam Spam Spam Spam/g' shopping
599 $ hg commit -m "SPAM SPAM SPAM"
600
601 Work I can keep getting localy
602
603 $ cd ../local
604 $ hg pull remote
605 pulling from $TESTTMP/remote
606 searching for changes
607 adding changesets
608 adding manifests
609 adding file changes
610 added 1 changesets with 1 changes to 1 files
611 (run 'hg update' to get a working copy)
612 $ hg tlog
613 e768beeb835c: 'SPAM SPAM SPAM'
614 39a85a192689: 'animals'
615 962d3a7d27ad: 'bathroom stuff'
616 02e33960e937: 'SPAM SPAM'
617 387187ad9bd9: 'adding fruit'
618 dfd3a2d7691e: 'adding condiment'
619 9ca060c80d74: 'SPAM'
620 7e82d3f3c2cb: 'Monthy Python Shopping list'
621
622 In the mean time I noticed you can't buy animals in a super market and I kill the animal changeset:
623
624 $ hg kill 39a85a192689 # issue warning here
625 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
626 working directory now at 962d3a7d27ad
627
628 The animals changeset is still displayed because the "SPAM SPAM SPAM" changeset
629 is neither dead or obsolete. My repository is in an unstable state again.
630
631 $ hg tlog
632 e768beeb835c: 'SPAM SPAM SPAM'
633 39a85a192689: 'animals'
634 962d3a7d27ad: 'bathroom stuff'
635 02e33960e937: 'SPAM SPAM'
636 387187ad9bd9: 'adding fruit'
637 dfd3a2d7691e: 'adding condiment'
638 9ca060c80d74: 'SPAM'
639 7e82d3f3c2cb: 'Monthy Python Shopping list'
640 $ hg tglog -r '::e768beeb835c'
641 o e768beeb835c: 'SPAM SPAM SPAM'
642 |
643 o 39a85a192689: 'animals'
644 |
645 @ 962d3a7d27ad: 'bathroom stuff'
646 |
647 o 02e33960e937: 'SPAM SPAM'
648 |
649 o 387187ad9bd9: 'adding fruit'
650 |
651 o dfd3a2d7691e: 'adding condiment'
652 |
653 o 9ca060c80d74: 'SPAM'
654 |
655 o 7e82d3f3c2cb: 'Monthy Python Shopping list'
656
657
658 # $ hg evolve # XXX not ready yet
659 # hg relocate --rev e768beeb835c 962d3a7d27ad
660
661 $ hg relocate -r e768beeb835c 'p1(39a85a192689)'
662 merging shopping
663
664 $ hg tlog
665 19098f8178f3: 'SPAM SPAM SPAM'
666 962d3a7d27ad: 'bathroom stuff'
667 02e33960e937: 'SPAM SPAM'
668 387187ad9bd9: 'adding fruit'
669 dfd3a2d7691e: 'adding condiment'
670 9ca060c80d74: 'SPAM'
671 7e82d3f3c2cb: 'Monthy Python Shopping list'
672
673 Handling Conflicting amend
674 ----------------------------------------------
675
676 We can detect that multiple diverging//conflicting amend have been made. There
677 will be a "evol-merge" command to merge conflicting amend