Kiln » HgInit » HgInit
Clone URL:  
02.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>HgInit: Setting up for a Team</title> <script src="c/jquery-1.4.1.js"></script> <script src="c/basic.js"></script> <link href="c/styles.css" rel="stylesheet" type="text/css" /> <script type="text/javascript"> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); </script> <script type="text/javascript"> try { var pageTracker = _gat._getTracker("UA-225715-20"); pageTracker._setDomainName("none"); pageTracker._setAllowLinker(true); pageTracker._trackPageview(); } catch(err) {}</script> </head> <body> <div id="kilnFlyOut"> <div class="flyoutscreenshot"> <img class="screenshot" src="i/dag.png" /> </div> <div class="flyouttext"> <strong>Kiln gives you:</strong> <ul> <li class="first"><a class="selected thumbnail" data-src="i/dag.png" href="convert.html">Mercurial-based<br/>version control</a></li> <li><a class="thumbnail" data-src="i/setup.png" href="convert.html">Straightforward<br/>setup</a></li> <li class="last"><a class="thumbnail" data-src="i/review.png" href="convert.html">Seamless<br/>code review</a></li> </ul> <a class="convert" href="convert.html" target="_blank" onClick="javascript: pageTracker._trackPageview('/outbound/flyout/freetrial.shop.fogcreek.com');"><img src="i/getstarted.gif" width="114" height="24" border="0" /></a> </div> <div class="flyoutteaser"><nobr><strong>Try Kiln free!</strong> Easy Mercurial hosting and more.</nobr></div> </div> <div class="toptop" align="left"> <ul> <li align="center"><a href="http://www.joelonsoftware.com/" onClick="javascript: pageTracker._trackPageview('/outbound/toptop/joelonsoftware.com');">Joel on Software</a></li> <li align="center"><a href="http://mercurial.selenic.com/" onClick="javascript: pageTracker._trackPageview('/outbound/toptop/mercurial.selenic.com');">Mercurial</a></li> <li align="center"><a href="index.html">Home</a></li> </ul> </div> <div id="dropshadow"></div> <div id="topnav"> <div class="tInterior"> <a href="index.html"> <img src="i/logo.png" border="0" alt="HgInit Home" /> </a> One of the benefits of using Mercurial is working with a team on the same code. Mercurial lets you each work independently, and merges your changes together.</div> </div> <div class="main"> <h1>Setting up for a Team</h1> <div class="content"> <p>The most common way to collaborate with Mercurial is to set up a central repository, in addition to the private repositories that we each have on our own computers. We can use the central repository sort of like a swap meet, where we get together to trade the changes we&#8217;ve been making.</p> <div><img src="i/02-repo.png" /></div> <div class="cheatcontent" style="margin-top:0px"> <div class="cheattop"> <div class="command">hg serve</div> </div> <p class="cheattext">runs a web server to make the current repository accessible over the Internet </p> <img src="i/cheatbot.png" width="241" height="41" /> </div> <p>The quick-and-dirty way to make a central repository is to use Mercurial&#8217;s built in web server&#8212;all you have to do is make a repository with <strong>hg init</strong> and then serve it on the web with <strong>hg serve</strong>. By default it will be served on port 8000.</p> <div class="codesnippet"> <div class="codetop"> </div> <pre> C:\&gt; <strong>mkdir CentralRepo</strong> C:\&gt; <strong>cd CentralRepo</strong> C:\CentralRepo&gt; <strong>hg init</strong> C:\CentralRepo&gt; <strong>hg serve</strong> </pre> <div class="codebottom"> </div> </div> <p>Since this computer is named <strong>joel.example.com</strong> I can just go to <strong>http://joel.example.com:8000/</strong> with a web browser and see that the server is up and running, even though the repository there is completely empty.</p> <div><img src="i/02-web.png" /></div> <div class="cheatcontent" style="margin-top:0px"> <div class="cheattop"> <div class="command">hg clone</div> </div> <p class="cheattext">make a complete copy of an entire repository </p> <img src="i/cheatbot.png" width="241" height="41" /> </div> <p>With the central web server running, I can <em>clone</em> this repository <em>from</em> the server <em>onto</em> my own computer for my own use. This repository is empty right now, so I&#8217;ll just get another empty repository when I clone it.</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel&gt; <strong>hg clone http://joel.example.com:8000/ recipes</strong> no changes found updating to branch default 0 files updated, 0 files merged, 0 files removed, 0 files unresolved C:\Users\joel&gt; <strong>cd recipes</strong> C:\Users\joel\recipes&gt; <strong>dir</strong> Volume in drive C has no label. Volume Serial Number is 84BD-9C2C Directory of C:\Users\joel\recipes 02/08/2010 02:46 PM &lt;DIR&gt; . 02/08/2010 02:46 PM &lt;DIR&gt; .. 02/08/2010 02:46 PM &lt;DIR&gt; .hg 0 File(s) 0 bytes 3 Dir(s) 41,852,125,184 bytes free </pre> <div class="codebottom"> </div> </div> <p>Now I&#8217;ll create a file called <strong>guac</strong> with my famous guacamole recipe.</p> <div class="edit1"> <div class="edittopbefore" > guac </div> <div class="editcontent"> * 2 ripe avocados<br> * 1/2 red onion, minced (about 1/2 cup)<br> * 1-2 serrano chiles, stems and seeds removed, minced<br> * 2 tablespoons cilantro leaves, finely chopped<br> * 1 tablespoon of fresh lime or lemon juice<br> * 1/2 teaspoon coarse salt<br> * A dash of freshly grated black pepper<br> * 1/2 ripe tomato, seeds and pulp removed, chopped<br><br> Crunch all ingredients together.<br> Serve with tortilla chips.<br> </div> <img src="i/edit-bot.gif" width="387" height="76" /> </div> <div style="clear: both;">&nbsp;</div> <p>I&#8217;ll add this file, and commit it as the first official version:</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>hg add</strong> adding guac C:\Users\joel\recipes&gt; <strong>hg commit</strong> </pre> <div class="codebottom"> </div> </div> <p>I&#8217;ll provide a commit comment:</p> <img src="i/02-commit0.png"> <p>I&#8217;m just going to quickly edit this file and make one small change, so that we have a little bit of history in the repository.</p> <div class="edit1"> <div class="edittopbefore"> guac </div> <div class="editcontent"> &#8230;<br> * A dash of freshly grated black pepper<br> * 1/2 ripe tomato, seeds and pulp removed, chopped<br><br> Crunch all ingredients together.<br> Serve with tortilla chips.<br> </div> <img src="i/edit-bot.gif" width="387" height="76" /> </div> <div class="edit2"> <img src="i/arrow2.gif" width="83" height="97" class="editArrow" /> <div class="edittopafter"> guac </div> <div class="editcontent"> &#8230;<br> * A dash of freshly grated black pepper<br> * 1/2 ripe tomato, seeds and pulp removed, chopped<br><br> <strong>Smoosh</strong> all ingredients together.<br> Serve with tortilla chips.<br> </div> <img src="i/edit-bot.gif" width="387" height="76" /> </div> <div style="clear: both;">&nbsp;</div> <p>And now to commit that change:</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>hg status</strong> M guac C:\Users\joel\recipes&gt; <strong>hg diff guac</strong> diff -r c1fb7e7fbe50 guac --- a/guac Mon Feb 08 14:50:08 2010 -0500 +++ b/guac Mon Feb 08 14:51:08 2010 -0500 @@ -7,5 +7,5 @@ * A dash of freshly grated black pepper * 1/2 ripe tomato, seeds and pulp removed, chopped -Crunch all ingredients together. +Smoosh all ingredients together. Serve with tortilla chips. C:\Users\joel\recipes&gt; <strong>hg com -m "Change crunch to smoosh"</strong> C:\Users\joel\recipes&gt; <strong>hg log</strong> changeset: 1:a52881ed530d tag: tip user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:51:18 2010 -0500 summary: Change crunch to smoosh changeset: 0:c1fb7e7fbe50 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:50:08 2010 -0500 summary: Initial version of guacamole recipe </pre> <div class="codebottom"> </div> </div> <p>Notice that when I committed that time, I used the <strong>-m</strong> argument, which I haven&#8217;t done before. That&#8217;s just a way to provide the commit message on the command line, without using an editor.</p> <p>OK, where are we? So far, I&#8217;ve got a central repository, and my clone of it. I&#8217;ve made two changes and committed them, but those changes are only in my clone&#8212;they&#8217;re not in the central repository yet. So the world looks like this:</p> <div><img src="i/02-repo-2.png" /></div> <div class="cheatcontent" style="margin-top:0px"> <div class="cheattop"> <div class="command">hg push</div> </div> <p class="cheattext"> push new changes from this repository into another </p> <img src="i/cheatbot.png" width="241" height="41" /> </div> <p>Now I&#8217;m going to use the <strong>hg push</strong> command, which will push my changes from my repository into the central repository:</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>hg push</strong> pushing to http://joel.example.com:8000/ searching for changes ssl required </pre> <div class="codebottom"> </div> </div> <p>Oh great. It figures that wouldn&#8217;t work. I neglected to think about the security implications of just running a random web server and allowing anybody in the world to push their stupid changes into it. Bear with me for a moment; I&#8217;m going to configure that server to allow anybody in the world to do anything they want to it. This can be done by editing the file .hg\hgrc on the server:</p> <div class="edit1"> <div class="edittopbefore"> .hg\hgrc </div> <div class="editcontent"> [web]<br /> push_ssl=False<br /> allow_push=*<br /> </div> <img src="i/edit-bot.gif" width="387" height="76" /> </div> <div style="clear: both;">&nbsp;</div> <p>Needless to say, this is rather unsafe, but if you&#8217;re on a nice protected LAN at work and there&#8217;s a good firewall and you trust everybody on your LAN, this is reasonably OK. Otherwise, you&#8217;ll want to read the advanced chapters on security.</p> <p>OK, time to fire up the server again:</p> <div class="codesnippet"> <div class="codetop"> </div> <pre> C:\CentralRepo> <strong>hg serve</strong> </pre> <div class="codebottom"> </div> </div> <p>And now I should be able to push into it:</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>hg push</strong> pushing to http://joel.example.com:8000/ searching for changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files </pre> <div class="codebottom"> </div> </div> <p>Yay! Now the world looks like this:</p> <img src="i/02-repo-3.png" /> <p>I know what you&#8217;re thinking. You&#8217;re thinking, &#8220;Gosh, Joel, that&#8217;s strange. Why do these repositories contain <em>changes</em> as opposed to <em>files</em>? Where&#8217;s that <strong>guac</strong> file?&#8221;</p> <p>Yeah, it&#8217;s weird. But that&#8217;s the way distributed version control works. Repositories just contain big stacks of changes. Imagine that a change is like one of those clear transparency sheets. When you have a bunch of transparency sheets, you stack them on each other in order, with the latest change on the top, and look down from above, and&#8212;tada!&#8212;you&#8217;re looking at the current version of the file. As you peel away transparencies from the top of the pile, you see older and older versions.</p> <p>We can use our web browser to peek into the central repository now:</p> <img src="i/02-web-2.png" /> <p>Exactly what you would expect.</p> <p>Now I want Rose to help me work on the recipe. Rose is on the test team. Everyone agrees that she reminds them of those middle-aged ladies you see in Vegas, sitting there slack-jawed for hours, shoveling quarter after quarter into the slot machines, only she&#8217;s testing software. You can throw her a new version of your code and she&#8217;ll test it on 23 different Linux distros, one after the other, expressionless, unmoving, pausing only to tell you that there&#8217;s a dot missing on one of the lower-case I&#8217;s in the Turkish version on Ubuntu Linux. Rose is a great tester but I swear sometimes she acts like a zombie.</p> <div class="codesnippetrose"> <div class="codetop"> </div> <pre class="rose"> C:\Users\rose&gt; <strong>hg clone http://joel.example.com:8000/ recipes</strong> requesting all changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files updating to branch default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved </pre> <div class="codebottom"> </div> </div> <p>Rose used the <strong>hg clone</strong> command to get her own, complete copy of the repository. <strong>hg clone</strong> takes two arguments: the URL of the repository and the name of the directory where you want it cloned. She made her own <strong>recipes</strong> folder.</p> <div class="codesnippetrose"> <div class="codetop"> </div> <pre class="rose"> C:\Users\rose&gt; <strong>cd recipes</strong> C:\Users\rose\recipes&gt; <strong>dir</strong> Volume in drive C has no label. Volume Serial Number is 84BD-9C2C Directory of C:\Users\rose\recipes 02/08/2010 03:23 PM &lt;DIR&gt; . 02/08/2010 03:23 PM &lt;DIR&gt; .. 02/08/2010 03:23 PM &lt;DIR&gt; .hg 02/08/2010 03:23 PM 394 guac 1 File(s) 394 bytes 3 Dir(s) 41,871,872,000 bytes free C:\Users\rose\recipes&gt; <strong>hg log</strong> changeset: 1:a52881ed530d tag: tip user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:51:18 2010 -0500 summary: Change crunch to smoosh changeset: 0:c1fb7e7fbe50 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:50:08 2010 -0500 summary: Initial version of guacamole recipe </pre> <div class="codebottom"> </div> </div> <p>Notice that when she types <strong>hg log</strong> she sees the whole history. She has actually downloaded the entire repository, with its complete history of everything that happened.</p> <p>Rose is going to make a change, and check it in:</p> <div class="edit1"> <div class="edittopbefore"> guac </div> <div class="editcontent"> * 2 ripe avocados<br> * 1/2 red onion, minced (about 1/2 cup)<br> * 1-2 serrano chiles, stems and seeds removed, minced<br> * 2 tablespoons cilantro leaves, finely chopped<br> * 1 tablespoon of fresh lime or lemon juice<br> &#8230; </div> <img src="i/edit-bot.gif" width="387" height="76" /> </div> <div class="edit2"> <img src="i/arrow2.gif" width="83" height="97" class="editArrow" /> <div class="edittopafter"> guac </div> <div class="editcontent"> * 2 ripe avocados<br> * 1/2 red onion, minced (about 1/2 cup)<br> * 1-2 <strong>habanero</strong> chiles, stems and seeds removed, minced<br> * 2 tablespoons cilantro leaves, finely chopped<br> * 1 tablespoon of fresh lime or lemon juice<br> &#8230;<br> </div> <img src="i/edit-bot.gif" width="387" height="76" /> </div> <div style="clear: both;">&nbsp;</div> <p>Now she commits it. Notice that she can do this even if the server is not running: the commit entirely happens on her machine.</p> <div class="codesnippetrose"> <div class="codetop"> </div> <pre class="rose"> C:\Users\rose\recipes&gt; <strong>hg diff</strong> diff -r a52881ed530d guac --- a/guac Mon Feb 08 14:51:18 2010 -0500 +++ b/guac Mon Feb 08 15:28:57 2010 -0500 @@ -1,6 +1,6 @@ * 2 ripe avocados * 1/2 red onion, minced (about 1/2 cup) -* 1-2 serrano chiles, stems and seeds removed, minced +* 1-2 habanero chiles, stems and seeds removed, minced * 2 tablespoons cilantro leaves, finely chopped * 1 tablespoon of fresh lime or lemon juice * 1/2 teaspoon coarse salt C:\Users\rose\recipes&gt; <strong>hg com -m "spicier kind of chile"</strong> C:\Users\rose\recipes&gt; <strong>hg log</strong> changeset: 2:689026657682 tag: tip user: Rose Hillman &lt;rose@example.com&gt; date: Mon Feb 08 15:29:09 2010 -0500 summary: spicier kind of chile changeset: 1:a52881ed530d user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:51:18 2010 -0500 summary: Change crunch to smoosh changeset: 0:c1fb7e7fbe50 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:50:08 2010 -0500 summary: Initial version of guacamole recipe </pre> <div class="codebottom"> </div> </div> <p>While Rose was making her change, I can make a change at the same time.</p> <div class="edit1"> <div class="edittopbefore"> guac </div> <div class="editcontent"> &#8230;<br> * 1/2 ripe tomato, seeds and pulp removed, chopped<br><br> Smoosh all ingredients together.<br> Serve with tortilla chips.<br> </div> <img src="i/edit-bot.gif" width="387" height="76" /> </div> <div class="edit2"> <img src="i/arrow2.gif" width="83" height="97" class="editArrow" /> <div class="edittopafter"> guac </div> <div class="editcontent"> &#8230;<br> * 1/2 ripe tomato, seeds and pulp removed, chopped<br><br> Smoosh all ingredients together.<br> Serve with <strong>potato</strong> chips. </div> <img src="i/edit-bot.gif" width="387" height="76" /> </div> <div style="clear: both;">&nbsp;</div> <p>After I check that in, you&#8217;ll see that my log shows something different as changeset #2 than Rose&#8217;s log.</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>hg com -m "potato chips. No one can eat just one."</strong> C:\Users\joel\recipes&gt; <strong>hg log</strong> changeset: 2:4ecdb2401ab4 tag: tip user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 15:32:01 2010 -0500 summary: potato chips. No one can eat just one. changeset: 1:a52881ed530d user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:51:18 2010 -0500 summary: Change crunch to smoosh changeset: 0:c1fb7e7fbe50 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:50:08 2010 -0500 summary: Initial version of guacamole recipe </pre> <div class="codebottom"> </div> </div> <p>Our histories are starting to diverge.</p> <img src="i/02-repo-4.png" /> <p>Don&#8217;t worry&#8230; in a minute we&#8217;ll see how to bring these diverging changes back together into one delicious habanero-based potato chip dip.</p> <div class="cheatcontent" style="margin-top:-15px"> <div class="cheattop"> <div class="command">hg outgoing</div> </div> <p class="cheattext">list changes in current repository waiting to be pushed </p> <img src="i/cheatbot.png" width="241" height="41" /> </div> <p>Rose can continue to work, disconnected, making as many changes as she wants, and either committing them, or reverting them, in her own repository. At some point, though, she&#8217;s going to want to share all the changes she&#8217;s been committing with the outside world. She can type <strong>hg outgoing</strong> which will show a list of changes that are waiting to be sent up to the central repository. These are the changes that <strong>hg push</strong> would send, if she were to <strong>hg push</strong>.</p> <div class="codesnippetrose"> <div class="codetop"> </div> <pre class="rose"> C:\Users\rose\recipes&gt; <strong>hg outgoing</strong> comparing with http://joel.example.com:8000/ searching for changes changeset: 2:689026657682 tag: tip user: Rose Hillman &lt;rose@example.com&gt; date: Mon Feb 08 15:29:09 2010 -0500 summary: spicier kind of chile </pre> <div class="codebottom"> </div> </div> <p>Think of <strong>hg outgoing</strong> like this: it simply lists any changes in the current repository that aren&#8217;t in the central repository.</p> <p>OK, so Rose pushes her changes.</p> <div class="codesnippetrose"> <div class="codetop"> </div> <pre class="rose"> C:\Users\rose\recipes&gt; <strong>hg push</strong> pushing to http://joel.example.com:8000/ searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files </pre> <div class="codebottom"> </div> </div> <p>And the world looks like this:</p> <img src="i/02-repo-5.png" /> <p>When I get back from my fourth latte break of the day, I&#8217;m ready to push my potato-chip change, too.</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>hg outgoing</strong> comparing with http://joel.example.com:8000/ searching for changes changeset: 2:4ecdb2401ab4 tag: tip user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 15:32:01 2010 -0500 summary: potato chips. No one can eat just one. C:\Users\joel\recipes&gt; <strong>hg push</strong> pushing to http://joel.example.com:8000/ searching for changes abort: push creates new remote heads! (did you forget to merge? use push -f to force) </pre> <div class="codebottom"> </div> </div> <p>Ahhh!! Failure! By the way&#8230; that message you see there? The one that says <strong>use push -f to force?</strong> That&#8217;s <em>terrible</em> advice. Never, ever, EVER use <strong>push -f</strong> to force. You will regret it. Trust me for now.</p> <p>The reason Rose&#8217;s push succeeded while mine failed is because potato chips do not go well with guacamole. Just kidding! I wanted to see if you were awake, there.</p> <p>The push failed because we both made changes, and so they need to be merged somehow, and Mercurial knows it.</p> <p>The first thing I&#8217;m going to do is get all those changes that are in the central repository that I don&#8217;t have yet, so I can merge them.</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>hg incoming</strong> comparing with http://joel.example.com:8000/ searching for changes changeset: 3:689026657682 tag: tip parent: 1:a52881ed530d user: Rose Hillman &lt;rose@example.com&gt; date: Mon Feb 08 15:29:09 2010 -0500 summary: spicier kind of chile C:\Users\joel\recipes&gt; <strong>hg pull</strong> pulling from http://joel.example.com:8000/ searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) </pre> <div class="codebottom"> </div> </div> <p>There&#8217;s some gibberish there about +1 heads. That&#8217;s because my repository, which used to just have three changes neatly stacked, is now a two-headed monster, with two different changes stacked precariously on top like this:</p> <div class="i"> <img src="i/02-repo-6.png" /> </div> <p>I&#8217;ve got both versions in my repository now&#8230; I&#8217;ve got my version:</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>type guac</strong> * 2 ripe avocados * 1/2 red onion, minced (about 1/2 cup) * 1-2 serrano chiles, stems and seeds removed, minced * 2 tablespoons cilantro leaves, finely chopped * 1 tablespoon of fresh lime or lemon juice * 1/2 teaspoon coarse salt * A dash of freshly grated black pepper * 1/2 ripe tomato, seeds and pulp removed, chopped Smoosh all ingredients together. Serve with potato chips. </pre> <div class="codebottom"> </div> </div> <p>And I&#8217;ve got Rose&#8217;s version:</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>hg cat -r 3 guac</strong> * 2 ripe avocados * 1/2 red onion, minced (about 1/2 cup) * 1-2 habanero chiles, stems and seeds removed, minced * 2 tablespoons cilantro leaves, finely chopped * 1 tablespoon of fresh lime or lemon juice * 1/2 teaspoon coarse salt * A dash of freshly grated black pepper * 1/2 ripe tomato, seeds and pulp removed, chopped Smoosh all ingredients together. Serve with tortilla chips. </pre> <div class="codebottom"> </div> </div> <p>And it&#8217;s up to me to merge them. Luckily, this is easy.</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>hg merge</strong> merging guac 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) C:\Users\joel\recipes&gt; <strong>type guac</strong> * 2 ripe avocados * 1/2 red onion, minced (about 1/2 cup) * 1-2 habanero chiles, stems and seeds removed, minced * 2 tablespoons cilantro leaves, finely chopped * 1 tablespoon of fresh lime or lemon juice * 1/2 teaspoon coarse salt * A dash of freshly grated black pepper * 1/2 ripe tomato, seeds and pulp removed, chopped Smoosh all ingredients together. Serve with potato chips. </pre> <div class="codebottom"> </div> </div> <p>Look! The <strong>hg merge</strong> command took my two heads and combined them together. In this case, since we both edited different parts of the file, there was no conflict at all and the merge went off without a hitch.</p> <div class="cheatcontent" style="margin-top:-65px"> <div class="cheattop"> <div class="command">hg merge</div> </div> <p class="cheattext">merge two heads </p> <img src="i/cheatbot.png" width="241" height="41" /> </div> <p>I still have to commit. This is important. If the merge failed, I could always revert and try again. Since the merge was successful, I&#8217;m going to commit it. Then I&#8217;ll be able to push my changes to the central repository.</p> <div class="codesnippetjoel"> <div class="codetop"> </div> <pre class="joel"> C:\Users\joel\recipes&gt; <strong>hg commit -m "merge"</strong> C:\Users\joel\recipes&gt; <strong>hg log</strong> changeset: 4:0849ca96c304 tag: tip parent: 2:4ecdb2401ab4 parent: 3:689026657682 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 16:07:23 2010 -0500 summary: merge changeset: 3:689026657682 parent: 1:a52881ed530d user: Rose Hillman &lt;rose@example.com&gt; date: Mon Feb 08 15:29:09 2010 -0500 summary: spicier kind of chile changeset: 2:4ecdb2401ab4 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 15:32:01 2010 -0500 summary: potato chips. No one can eat just one. changeset: 1:a52881ed530d user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:51:18 2010 -0500 summary: Change crunch to smoosh changeset: 0:c1fb7e7fbe50 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:50:08 2010 -0500 summary: Initial version of guacamole recipe C:\Users\joel\recipes&gt; <strong>hg out</strong> comparing with http://joel.example.com:8000/ searching for changes changeset: 2:4ecdb2401ab4 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 15:32:01 2010 -0500 summary: potato chips. No one can eat just one. changeset: 4:0849ca96c304 tag: tip parent: 2:4ecdb2401ab4 parent: 3:689026657682 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 16:07:23 2010 -0500 summary: merge C:\Users\joel\recipes&gt; <strong>hg push</strong> pushing to http://joel.example.com:8000/ searching for changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files </pre> <div class="codebottom"> </div> </div> <p>And now the central repository has the same thing as I do:</p> <img src="i/02-repo-7.png" /> <p>OK, I have Rose&#8217;s changes, and my changes, but Rose doesn&#8217;t have my changes yet.</p> <p>One thing I forgot to tell you about Rose. She&#8217;s a doctor. Yep. A medical doctor. Isn&#8217;t that weird? She was a hotshot pediatrician at Mt. Sinai, probably earning five times as much as this crappy joint pays its testers. Nobody really knows why she left the field of medicine. The other testers think something tragic happened. She had a family, once, too; there&#8217;s a picture of a cute ten year old on her desk, but now she lives alone, and we don&#8217;t want to pry.</p> <p>Rose needs to pull the latest, incoming stuff from the repository to get it.</p> <div class="codesnippetrose"> <div class="codetop"> </div> <pre class="rose"> C:\Users\rose\recipes&gt; <strong>hg pull</strong> pulling from http://joel.example.com:8000/ searching for changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files (run 'hg update' to get a working copy) </pre> <div class="codebottom"> </div> </div> <p>Got it. Now, you may find this a bit odd, but even though Rose pulled those new changes into her repository, <em>they&#8217;re not in her working directory yet.</em></p> <div class="codesnippetrose"> <div class="codetop"> </div> <pre class="rose"> C:\Users\rose\recipes&gt; <strong>type guac</strong> * 2 ripe avocados * 1/2 red onion, minced (about 1/2 cup) * 1-2 habanero chiles, stems and seeds removed, minced * 2 tablespoons cilantro leaves, finely chopped * 1 tablespoon of fresh lime or lemon juice * 1/2 teaspoon coarse salt * A dash of freshly grated black pepper * 1/2 ripe tomato, seeds and pulp removed, chopped Smoosh all ingredients together. Serve with tortilla chips. </pre> <div class="codebottom"> </div> </div> <p>See that? She&#8217;s still working with Tortilla chips. Tortilla chips!</p> <p>She <em>does</em> have my new changes somewhere in her repository&#8230;</p> <div class="codesnippetrose"> <div class="codetop"> </div> <pre class="rose"> C:\Users\rose\recipes&gt; <strong>hg log</strong> changeset: 4:0849ca96c304 tag: tip parent: 3:4ecdb2401ab4 parent: 2:689026657682 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 16:07:23 2010 -0500 summary: merge changeset: 3:4ecdb2401ab4 parent: 1:a52881ed530d user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 15:32:01 2010 -0500 summary: potato chips. No one can eat just one. changeset: 2:689026657682 user: Rose Hillman &lt;rose@example.com&gt; date: Mon Feb 08 15:29:09 2010 -0500 summary: spicier kind of chile changeset: 1:a52881ed530d user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:51:18 2010 -0500 summary: Change crunch to smoosh changeset: 0:c1fb7e7fbe50 user: Joel Spolsky &lt;joel@joelonsoftware.com&gt; date: Mon Feb 08 14:50:08 2010 -0500 summary: Initial version of guacamole recipe </pre> <div class="codebottom"> </div> </div> <div class="cheatcontent" style="margin-top:0px"> <div class="cheattop"> <div class="command">hg parent</div> </div> <p class="cheattext">show the changeset that&#8217;s in the working directory </p> <img src="i/cheatbot.png" width="241" height="41" /> </div> <p>They&#8217;re just not in her working directory. That&#8217;s because she&#8217;s still working off of changeset #2. You can see this with the &#8220;parent&#8221; command:</p> <div class="codesnippetrose"> <div class="codetop"> </div> <pre class="rose"> C:\Users\rose\recipes&gt; <strong>hg parent</strong> changeset: 2:689026657682 user: Rose Hillman &lt;rose@example.com&gt; date: Mon Feb 08 15:29:09 2010 -0500 summary: spicier kind of chile </pre> <div class="codebottom"> </div> </div> <p>Mercurial is being nice to us. It&#8217;s always safe to pull; all it does is get us the latest changes that other people have been making. We can switch to working with them later, at our own convenience.<p> <p>Remember that the <strong>hg up</strong> command with no arguments will change the working directory to the <em>tip</em> (the absolute TOP changeset), in this case number 4:</p> <div class="codesnippetrose"> <div class="codetop"> </div> <pre class="rose"> C:\Users\rose\recipes&gt; <strong>hg up</strong> 1 files updated, 0 files merged, 0 files removed, 0 files unresolved C:\Users\rose\recipes&gt; <strong>type guac</strong> * 2 ripe avocados * 1/2 red onion, minced (about 1/2 cup) * 1-2 habanero chiles, stems and seeds removed, minced * 2 tablespoons cilantro leaves, finely chopped * 1 tablespoon of fresh lime or lemon juice * 1/2 teaspoon coarse salt * A dash of freshly grated black pepper * 1/2 ripe tomato, seeds and pulp removed, chopped Smoosh all ingredients together. Serve with potato chips. </pre> <div class="codebottom"> </div> </div> <p>And now, she&#8217;s looking at the latest version with everybody&#8217;s changes.</p> <p>When you&#8217;re working on a team, your workflow is going to look a lot like this:</p> <ol> <li>If you haven&#8217;t done so in a while, get the latest version that everyone else is working off of:</li> <ul> <li>hg pull</li> <li>hg up</li> </ul> <li>Make some changes</li> <li>Commit them (locally)</li> <li>Repeat steps 2-3 until you&#8217;ve got some nice code that you&#8217;re willing to inflict on everyone else</li> <li>When you&#8217;re ready to share:</li> <ul> <li>hg pull to get everyone else&#8217;s changes (if there are any)</li> <li>hg merge to merge them into yours</li> <li>test! to make sure the merge didn&#8217;t screw anything up</li> <li>hg commit (the merge)</li> <li>hg push</li> </ul> </ol> <h2>Test yourself</h2> <p>Here are the things you should know how to do after reading this tutorial:</p> <ol> <li>Set up a central repository and let team members clone off of it</li> <li>Push changes into the central repository</li> <li>Pull changes from the central repository</li> <li>Merge changes from different contributors</li> </li> </ol> <div class="footer"> <div class="footernav" id="home" align="center"><a href="index.html"><span class="angleQuote">&#171;</span> Home</a></div> <div class="footernav" id="comingup">Next, we talk about how to fix <span style="text-decoration: line-through;">misstakes</span> mistakes. </div> <div class="footernav" id="next" align="center"><a href="03.html">Next <span class="angleQuote">&#187;</span></a></div> </div> <div class="pagebottom"> <div class="bottomimg"> <a href="http://www.kilnhg.com" target="_blank" id="logoLink" title="KilnHg.com" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/klinhg.com');">&nbsp;</a> <div class="bottomtext">This tutorial was brought to you by the fine folks at Fog Creek Software, makers of Kiln, a version control system powered by Mercurial</div> <div class="bottomtext"><strong>Kiln gives you:</strong><br /> &#8226; A complete version control system based on <a href="http://mercurial.selenic.com/" target="_blank" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/mercurial.selenic.com');">Mercurial</a><br /> &#8226; <a href="http://fogcreek.com/kiln/learnmore.html#hist_BranchAndMerge" target="_blank" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/branchandmerge.kilnhg.com');">Branching and merging</a> that really works<br /> &#8226; <a href="http://fogcreek.com/kiln/learnmore.html#hist_Tools" target="_blank" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/tools.kilnhg.com');">Straightforward setup</a> on your server, or simple secure hosting on ours<br /> &#8226; Seamlessly integrated <a href="http://fogcreek.com/kiln/learnmore.html#hist_StartReviewsEffortlessly" target="_blank" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/startreviews.kilnhg.com');">code review</a><br /> </div> <div class="bottomtext getStarted"> <a href="convert.html" target="_blank" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/freetrial.shop.fogcreek.com');"><img src="i/getstarted.gif" width="114" height="24" border="0" /></a> </div> </div> <div class="about"> <p> <strong>Any questions?</strong> </p> <p> If you have any questions about the material in this tutorial, no matter how newbie, ask them at <a href="http://kiln.stackexchange.com/" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/kiln.stackexchange.com');">the Kiln Knowledge Exchange.</a> </p> <p> <strong>About the author.</strong> </p> <p> Joel Spolsky is the founder of <a href="http://fogcreek.com" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/fogcreek.com');">Fog Creek Software</a>, a New York company that proves that you can treat programmers well and still be profitable. Programmers get private offices, free lunch, and work 40 hours a week. Customers only pay for software if they&#8217;re delighted. Fog Creek makes <a href="http://www.fogbugz.com" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/fogbugz.com');">FogBugz</a>, <a href="http://www.kilnhg.com/" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/text.kilnhg.com');">Kiln</a>, and <a href="https://www.copilot.com/" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/copilot.com');">Fog Creek Copilot</a>. Joel's blog <a href="http://www.joelonsoftware.com/" onClick="javascript: pageTracker._trackPageview('/outbound/bottom/joelonsoftware.com');">Joel on Software</a> is read by programmers everywhere. </p> </div> <!-- close bottom div --> </div> <!-- close "content" column --> </div> <!-- close "main" div --> </div> <!-- bottom grey bar --> <div class="botbot" align="left"> </div> <!-- Google Website Optimizer Tracking Script --> <script type="text/javascript"> if(typeof(_gat)!='object')document.write('<sc'+'ript src="http'+ (document.location.protocol=='https:'?'s://ssl':'://www')+ '.google-analytics.com/ga.js"></sc'+'ript>')</script> <script type="text/javascript"> try { var gwoTracker=_gat._getTracker("UA-225715-15"); gwoTracker._trackPageview("/2687020024/test"); }catch(err){}</script> <!-- End of Google Website Optimizer Tracking Script --> </body> </html>