Source

hgbook-ru / ru / ch02-tour-basic.xml

  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
<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->

<chapter id="chap:tour-basic">
  <?dbhtml filename="a-tour-of-mercurial-the-basics.html"?>
  <title>Экскурсия по Mercurial: основы</title>

  <sect1 id="sec:tour:install">
    <title>Установка Mercurial на вашем компьютере</title>

    <para id="x_1">Прекомпилированные пакеты Mercurial доступны для каждой популярной операционной системы. Это позволяет вам начать использование Mercurial на вашем компьютере немедленно.</para>

    <sect2>
      <title>Windows</title>

      <para id="x_c">Лучшей версией Mercurial для windows является TortoiseHg, который можно найти на сайте <ulink url="http://tortoisehg.org">http://tortoisehg.org</ulink>. Этот пакет не имеет внешних зависимостей, он <quote>просто работает</quote>. Он позволяет использовать командную строку и графический пользовательский интерфейс.</para>

    </sect2>

    <sect2>
      <title>Mac OS X</title>

      <para id="x_a">Ли Канти публикует инсталлятор mercurial для mac os x на <ulink url="http://mercurial.berkwood.com">http://mercurial.berkwood.com</ulink>.</para>
    </sect2>

    <sect2>
      <title>Linux</title>

      <para id="x_2">В силу того, что каждый дистрибутив Linux использует свои собственные менеджеры пакетов, а также стратегии и темпы разработки, трудно дать подробную инструкции по установке Mercurial. Версия Mercurial, которую вы получите очень зависит от того, насколько активен тот, кто занимается созданием пакетов для вашего дистрибутива.</para>

      <para id="x_3">Чтобы не усложнять процесс, я сфокусируюсь на установке Mercurial из командной строки в наиболее популярных дистрибутивах Linux. Большинство из них располагают менеждерами пакетов с графическим интерфейсом, что позволит вам установить Mercurial нажатием одной кнопки. Пакет для установки называется <literal>mercurial</literal>.</para>

      <itemizedlist>
	<listitem><para id="x_4">Ubuntu и Debian:</para>
	  <programlisting>apt-get install mercurial</programlisting></listitem>
	<listitem><para id="x_5">Fedora:</para>
	  <programlisting>yum install mercurial</programlisting></listitem>
	<listitem><para id="x_715">OpenSUSE:</para>
	  <programlisting>zypper install mercurial</programlisting></listitem>
	<listitem><para id="x_6">Gentoo:</para>
	  <programlisting>emerge mercurial</programlisting></listitem>
      </itemizedlist>

    </sect2>
    <sect2>
      <title>Solaris</title>

      <para id="x_9">SunFreeWare, на <ulink url="http://www.sunfreeware.com">http://www.sunfreeware.com</ulink> , предоставляет готовые пакеты Mercurial.</para>

    </sect2>

  </sect1>

  <sect1>
    <title>Начало работы</title>

    <para id="x_e">Для начала выполним команду <command role="hg-cmd">hg version</command>, чтобы удостовериться, что Mercurial установлен правильно. Какая версия на самом деле &emdash; неважно, главное, что она вообще что-то выводит.</para>

    &interaction.tour.version;

    <sect2>
      <title>Встроенная справка</title>

      <para id="x_f">У Mercurial есть встроенная справка. Очень сложно переоценить ее наличие, особенно когда ваша работа остановилась из-за того, что вы не можете вспомнить как выполнить какую-то команду. Если Вы застопорились, просто выполните <command role="hg-cmd">hg help</command>, и на экран выведется краткий список команд с описанием назначения каждой из них. Если же вы еще и укажите конкретную команду (см. ниже), выведется подробная информация именно о ней.</para>

	&interaction.tour.help;

	<para id="x_10">Для большей детализации выполните <command role="hg-cmd">hg help <option role="hg-opt-global">-v</option></command>. Опция <option role="hg-opt-global">-v</option> - сокращение от <option role="hg-opt-global">--verbose</option>, заставит Mercurial выводить больше информации, чем обычно.</para>

    </sect2>
  </sect1>
  <sect1>
    <title>Работа с репозиторием</title>

    <para id="x_11">В Mercurial все происходит внутри <emphasis>репозитория</emphasis>. Репозиторий проекта содержит все файлы, которые <quote>относятся</quote> к проекту, а также историю изменений этих файлов.</para>

    <para id="x_12">В репозитории нет никакой магии, это просто каталог в файловой системе, который Mercurial обрабатывает особым образом. Вы можете переименовать или удалить репозиторий в любое время через командную строку или вашим собственным файловым менеджером.</para>

    <sect2>
      <title>Создание локальной копии репозитория</title>

      <para id="x_13"><emphasis>Копирование</emphasis> репозитория кое-чем отличается. Хотя вы можете скопировать репозиторий как обычный каталог, лучше использовать встроенную команду Mercurial. Она называется <command role="hg-cmd">hg clone</command>, потому что создает идентичную копию существующего репозитория.</para>

      &interaction.tour.clone;

      <para id="x_67c">Одно из преимуществ использования <command role="hg-cmd">hg clone</command> в том, что как мы видим выше, она позволяет клонировать репозитории по сети. Другим является то, что она запоминает, откуда мы его клонировали. Скоро мы убедимся, что это полезно, когда мы захотим принести новые изменения из другого репозитария.</para>

      <para id="x_14">Если клонирование прошло успешно, то у вас должен появится каталог под названием <filename class="directory">hello</filename>. В нем должны быть какие-то файлы.</para>

      &interaction.tour.ls;

      <para id="x_15">У файлов в нашем репозитории то же самое содержимое и история, как и в исходном.</para>

      <para id="x_16">Каждый репозиторий Mercurial полон, самодостаточнен и независим. Он содержит свою собственную копию файлов проекта и их историю. Склонированный репозиторий помнит, откуда он был склонирован, но не общается с тем репозиторием, да и ни с каким другим тоже, до тех пор пока вы ему не скажете.</para>

      <para id="x_17">Это означает, что вы можете свободно экспериментировать с вашим репозиторием. Это безопасно, потому что ваш репозиторий &emdash; <quote>закрытая песочница</quote>, изменения в котором не повлияют ни на что, кроме него самого.</para>

    </sect2>
    <sect2>
      <title>Что есть в репозитории?</title>

      <para id="x_18">Когда мы более пристально присмотримся к репозиторию, мы увидим, что он содержит каталог под названием <filename class="directory">.hg</filename>. Это место, где Mercurial хранит все метаданные репозитория.</para>

      &interaction.tour.ls-a;

      <para id="x_19">Содержание каталога <filename class="directory">.hg</filename> и его подкаталогов является собственностью Mercurial. Со всеми остальными файлами и каталогами в репозитории мы можем делать что угодно.</para>

      <para id="x_1a">Строго говоря, каталог <filename class="directory">.hg</filename> &emdash; это и есть <quote>настоящий</quote> репозиторий, а все остальные файлы и каталоги рядом с ним называются <emphasis>рабочим каталогом</emphasis>. Разницу запомнить довольно просто &emdash; <emphasis>репозиторий</emphasis> содержит всю <emphasis>историю</emphasis> вашего проекта, в то время как <emphasis>рабочий каталог</emphasis> содержит <emphasis>слепок</emphasis> вашего проекта в определенной точке истории.</para>

    </sect2>
  </sect1>
  <sect1>
    <title>Путешествие по истории</title>

    <para id="x_1b">Самое первое, что вы захотите сделать с новым, неизвестным репозиторием &emdash; изучить его историю. Команда <command role="hg-cmd">hg log</command> предназначена как раз для этого.</para>

    &interaction.tour.log;

    <para id="x_1c">По умолчанию, эта команда выводит краткую информацию о каждом изменении в проекте, которое было зафиксировано. В терминологии Mercurial мы называем эти зафиксированные события <emphasis>ревизией</emphasis> (<emphasis>changeset</emphasis>), потому что она может содержать изменения в различных файлах.</para>

    <para id="x_1d"><command role="hg-cmd">hg log</command> выводит записи со следующими полями:</para>

    <itemizedlist>
      <listitem><para id="x_1e"><literal>changeset</literal> (ревизия). Она состоит из десятичного числа, двоеточия и строки шестнадцатеричных цифр. Это <emphasis>идентификаторы</emphasis> ревизии. Строка шестнадцатеричных цифр представляет собой уникальный идентификатор: та же строка шестнадцатеричных цифр будет обозначать этот набор изменений в каждой копии этого хранилища. Номер короче и проще напечатать, чем строку шестнадцатеричных цифр, но он не является уникальным: это же число в двух различных копиях репозитория могут иметь различные ревизии.</para>
      </listitem>
      <listitem><para id="x_1f"><literal>user</literal> (пользователь). Идентификатор человека, создавшего ревизию. Там может находится все, что угодно, но чаще это имя человека и адрес электронной почты.</para></listitem>
      <listitem><para id="x_20"><literal>date</literal>. Дата и время, когда была создана ревизия, а также часовой пояс, в котором она была создана. (Дата и время приведены относительно этого часового пояса, они указывают сколько времени было для того, кто создал ревизию)</para></listitem>
      <listitem><para id="x_21"><literal>summary</literal>. Первая строка комментария к ревизии, который оставил её автор.</para></listitem>
      <listitem>
	<para id="x_67d">Некоторые наборы изменений, таких, как первая, имеют поле <literal>tag</literal> (тэг). Теги это еще один способ идентифицировать набор изменений, придав ему легкое для запоминания имя. (Тег с названием <literal>tip</literal> специальный: он всегда относится к новейшему изменению в репозитарии.)</para>
      </listitem>
    </itemizedlist>

    <para id="x_22">По умолчанию <command role="hg-cmd">hg log</command> выводит очень общие сведения, с отсутствием множества деталей.</para>

    <para id="x_23"><xref linkend="fig:tour-basic:history"/> содержит графическое представление истории репозитория <filename class="directory">hello</filename>, что слегка облегчает понимание того, в каком направлении <quote>развивается</quote> его история. Мы будем возвращаться к этому рисунку в этой и следующей главах.</para>

    <figure id="fig:tour-basic:history">
      <title>Графическое представление истории репозитория <filename class="directory">hello</filename></title>
      <mediaobject>
	<imageobject><imagedata fileref="figs/tour-history.png"/></imageobject>
	<textobject><phrase>XXX add text</phrase></textobject>
      </mediaobject>
    </figure>

    <sect2>
      <title>Изменения, ревизии и общение с другими людьми</title>

      <para id="x_25">Английский язык печально известен своей небрежностью, а компьютерная наука имеет обширную историю неразберихи в терминах (зачем один термин, если можно использовать четыре). В контроле версий есть множество слов и фраз, означающих одно и то же. Если речь идет об истории в Mercurial, вы увидите, что слово <quote>changeset</quote> (набор изменений), обычно сокращается до <quote>change</quote>, или (при письме), до <quote>cset</quote>, а иногда <quote>changeset</quote> называют <quote>revision</quote> (ревизия) или <quote>rev</quote>.</para>

      <para id="x_26">Не важно, какое <emphasis>слово</emphasis> вы используете для концепции <quote>ревизии</quote>, <emphasis>идентификатор</emphasis>, по которому вы ссылаетесь на <quote><emphasis>определенную</emphasis> ревизию</quote> имеет гораздо большее значение. Вспомните, что <literal>ревизия</literal> в выводе команды <command role="hg-cmd">hg log</command> идентифицируется номером и шестнадцатеричной строкой.</para>
      <itemizedlist>
	<listitem><para id="x_27">Номер ревизии удобен для записи, но действителен <emphasis>только в пределах своего репозитория</emphasis>.</para></listitem>
	<listitem><para id="x_28">Шестнадцатеричная строка &emdash; <emphasis>постоянный, неизменный параметр</emphasis>, который всегда идентифицирует одну и ту же ревизию в <emphasis>каждой</emphasis> копии репозитория.</para></listitem></itemizedlist>

      <para id="x_29">Это различие очень важно. Если вы отправите кому-нибудь письмо с упоминанием <quote>ревизии 33</quote>, существует большая вероятность, что их ревизия 33 будет <emphasis>совсем другой</emphasis>. Причиной этого является то, что номер ревизии зависит от порядка, в котором ревизии попадают в репозиторий, и нет никакой гарантии, что одни и те же изменения произойдут в одинаковом порядке в различных репозиториях. Три изменения <literal>А, Б и В</literal> запросто могут появится в одном репозитории в порядке <literal>0,1,2</literal>, а в другом &emdash; <literal>0,2,1</literal>.</para>

      <para id="x_2a">Mercurial использует номера ревизий исключительно для удобства. Если вам нужно обсудить с кем-то конкретную ревизию, или по какой-то другой причине ссылаться на нее (в багтрекере, например), используйте шестнадцатеричный идентификатор.</para>

    </sect2>
    <sect2>
      <title>Просмотр определенных ревизий</title>

      <para id="x_2b">Чтобы ограничить вывод команды <command role="hg-cmd">hg log</command> до одной ревизии, используйте опцию <option role="hg-opt-log">-r</option> (или <option role="hg-opt-log">--rev</option>). Вы можете использовать или номер ревизии или ее идентификатор, а также запросить ревизий столько, сколько вам захочется.</para>

      &interaction.tour.log-r;

      <para id="x_2c">Если вы хотите увидеть историю нескольких ревизий, но не хотите просматривать их все, можете указать <emphasis>диапазон</emphasis>, как бы выражая мысль: <quote>Мне нужны все ревизии от <literal>А</literal> до <literal>Б</literal> включительно</quote>.</para>
      
	&interaction.tour.log.range;

      <para id="x_2d">Mercurial учитывает порядок, в котором ревизии были указаны, так что <command role="hg-cmd">hg log -r 2:4</command> выводит ревизии 2,3 и 4. Тогда как <command role="hg-cmd">hg log -r 4:2</command> &emdash; 4,3 и 2.</para>

    </sect2>
    <sect2>
      <title>Подробности</title>

      <para id="x_2e">В то время как информация, которую выводит <command role="hg-cmd">hg log</command> полезна, если вы знаете что ищете, вам может понадобиться полное описание изменений или список измененных файлов, если вы хотите узнать та ли это ревизия, что вам нужна. Команда <command role="hg-cmd">hg log</command> с аргументом <option role="hg-opt-global">-v</option> (<option role="hg-opt-global">--verbose</option>) предоставит вам такую возможность.</para>

      &interaction.tour.log-v;

      <para id="x_2f">Если вы хотите видеть описание и то как изменялось содержимое, добавьте опцию <option role="hg-opt-log">-p</option> (или <option role="hg-opt-log">--patch</option>). Будет показываться содержание изменений в <emphasis>едином diff</emphasis> (если вы никогда не видели формат унифицированного diff раньше, см. <xref linkend="sec:mq:patch"/>).</para>

      &interaction.tour.log-vp;

      <para id="x_67e">Опция <option role="hg-opt-log">-p</option> очень полезна, поэтому следует её запомнить.</para>

    </sect2>
  </sect1>

  <sect1>
    <title>Об опциях команд</title>

    <para id="x_30">Давайте сделаем перерыв в изучении команд Mercurial и обсудим шаблоны работы с ними. Это будет вам полезно, когда мы продолжим наше турне.</para>

    <para id="x_31">Mercurial имеет простой и последовательный подход в работе с опциями, которые вы можете передавать командам. Это следует из соглашений по опциям, которые являются общими для современных Linux и Unix систем.</para>

    <itemizedlist>
      <listitem>
	<para id="x_32">Каждая опция имеет длинное имя. К примеру, как мы уже видели, команда <command role="hg-cmd">hg log</command> принимает параметр <option role="hg-opt-log">--rev</option>.</para>
      </listitem>
      <listitem>
	<para id="x_33">Также большинство опций имеют короткие имена. Вместо <option role="hg-opt-log">--rev</option> можно использовать <option role="hg-opt-log">-r</option>. Не все опции имеют короткие имена, потому как некоторые из них просто редко используются.</para>
      </listitem>
      <listitem>
	<para id="x_34">Длинные опции начинаются с двух тире (<option role="hg-opt-log">--rev</option>), а короткие начинаются с одного (<option role="hg-opt-log">-r</option>).</para>
      </listitem>
      <listitem>
	<para id="x_35">Имена опций и их применение в командах согласовано. Например, все команды, позволяющие указывать ID или номер ревизии принимают оба аргумента <option role="hg-opt-log">-r</option> и <option role="hg-opt-log">--rev</option>.</para>
      </listitem>
      <listitem>
	<para id="x_67f">При использовании коротких опций, вы можете печатать их вместе. Например, команда <command role="hg-cmd">hg log -v -p -r 2</command> может быть записана в виде <command role="hg-cmd">hg log -vpr2</command>.</para>
      </listitem>
    </itemizedlist>

    <para id="x_36">В примерах в этой книге я использую короткую запись аргументов, а не длинную. Это всего лишь дело моего вкуса, так что не ищите в этом скрытого смысла.</para>

    <para id="x_37">Большинство выводящих какую-то информацию команд выдадут большее количество информации, если им передать опцию <option role="hg-opt-global">-v</option> (или <option role="hg-opt-global">--verbose</option>), или меньшее, если передать опцию <option role="hg-opt-global">-q</option> (или <option role="hg-opt-global">--quiet</option>).</para>

    <note>
      <title>Вариант наименования опций</title>

      <para id="x_680">Почти всегда в командах Mercurial названия опций придерживаются единой концепции. Для примера, если команда работает с наборами изменений, вы всегда будете идентифицировать их опциями <option role="hg-opt-log">--rev</option> или <option role="hg-opt-log">-r</option>. Такая последовательность в использовании имён делает более лёгким запоминание опций различных команд.</para>
    </note>

  </sect1>
  <sect1>
    <title>Создание и анализ изменений</title>

    <para id="x_38">Так как мы уже умеем просматривать историю в Mercurial, можно заняться внесением изменений и их изучением.</para>

    <para id="x_39">Первое, что необходимо сделать &emdash; изолировать наш эксперимент в его собственном репозитории. Для этого используется команда <command role="hg-cmd">hg clone</command>, но так как у нас уже есть копия репозитория локально, то мы можем клонировать её вместо клонирования по сети. Это действие значительно быстрее, а кроме того, в большинстве случаев использует меньше места на диске<footnote> <para id="x_681">Экономия пространства возникает, когда источник и получатель репозитория находятся на одной файловой системе, в этом случае Mercurial будет использовать жесткие ссылки, чтобы использовать политику совместного использования копрование-при-записи для его внутренних метаданных. Если это объяснение ничего для вас не значит, не беспокойтесь: все происходит прозрачно и автоматически, и вам не нужно ничего понимать.</para>
	</footnote>.</para>

    &interaction.tour.reclone;

    <para id="x_3a">Кстати говоря, хорошей идеей является хранение <quote>нетронутой</quote> копии удалённого репозитория, который можно использовать для создания временных клонов для получения <quote>песочниц</quote> для каждой задачи, над которой вам хочется поработать. Это позволяет вам работать над множеством задач одновременно, изолированных друг от друга до завершения и вашей готовности их интегрировать. Потому как локальные клоны настолько <quote>дёшевы</quote>, что их создание и уничтожение в любое удобное время практически не несёт накладных расходов.</para>

    <para id="x_3b">В нашем хранилище <filename class="directory">my-hello</filename>, мы имеем файл <filename>hello.c</filename> &emdash; классическую программу <quote>Hello, World</quote>.</para>

    &interaction.tour.cat1;

    <para id="x_682">Давайте отредактируем этот файл чтоб он печатал на выходе вторую строку.</para>

    &interaction.tour.cat2;

    <para id="x_3c">Команда Mercurial <command role="hg-cmd">hg status</command> покажет, что Mercurial знает о файлах в репозитории.</para>

    &interaction.tour.status;

    <para id="x_3d"><command role="hg-cmd">hg status</command> выводит информацию не обо всех файлах, а только об изменённых: это строка, начинающаяся с буквы <quote><literal>M</literal></quote> для <filename>hello.c</filename>. Пока вы не укажете это специально, <command role="hg-cmd">hg status</command> не будет выводить информацию про файлы, которые не изменились.</para>

    <para id="x_3e"><quote><literal>M</literal></quote> показывает, что Mercurial оповещен о модификации <filename>hello.c</filename>. Мы не <emphasis>уведомляли</emphasis> Mercurial о том, что изменили файл ни перед, ни после окончания работы, он способен самостоятельно находить изменения.</para>

    <para id="x_3f">Иногда мало просто знать только о факте изменения файла, и мы предпочли бы знать, <emphasis>какие</emphasis> точно изменения были сделаны. Для этого используется команда <command role="hg-cmd">hg diff</command>.</para>

    &interaction.tour.diff;

    <tip>
      <title>Объяснение патчей</title>

      <para id="x_683">Напомню, что нужно посмотреть <xref linkend="sec:mq:patch"/>, если вы не знаете, как читать вывод команды выше.</para>
    </tip>
  </sect1>
  <sect1>
    <title>Запись изменений в новую ревизию</title>

    <para id="x_40">Мы можем изменять файлы, собирать и тестировать изменения и использовать команды <command role="hg-cmd">hg status</command>, <command role="hg-cmd">hg diff</command> для анализа изменений, пока мы не будем удовлетворены ими и не достигнем естественной точки, когда захочется записать проделанную работу в новую ревизию.</para>

    <para id="x_41">Команда <command role="hg-cmd">hg commit</command> позволяет создать новую ревизию. Для простоты, мы будем называть этот процесс <quote>сделать коммит</quote> или <quote>закоммитить</quote>.</para>

    <sect2>
      <title>Установка имени пользователя</title>

      <para id="x_42">В первый раз выполнение команды <command role="hg-cmd">hg commit</command> может пройти неудачно. Mercurial записывает ваше имя и адрес в каждую ревизию, чтобы вы или другие пользователи могли связаться с автором каждого изменения. Mercurial пытается найти наиболее разумное имя пользователя для коммита. Поиск происходит в следующем порядке:</para>
      <orderedlist>
	<listitem><para id="x_43">Если в команде <command role="hg-cmd">hg commit</command> вы указали опцию <option role="hg-opt-commit">-u</option>, с последующим именем пользователя, то оно будет обладать наивысшим приоритетом.</para></listitem>
	<listitem><para id="x_44">Если у вас установлена переменная окружения <envar>HGUSER</envar>, то следующей будет проверена она.</para></listitem>
	<listitem><para id="x_45">Если вы создали в своей домашней директории файл <filename role="special">.hgrc</filename>, и в нём есть директива <envar role="rc-item-ui">username</envar> &emdash; будет использована она. Чтобы узнать, как должен выглядеть содержимое этого файла, смотрите <xref linkend="sec:tour-basic:username"/>.</para></listitem>
	<listitem><para id="x_46">Если у вас установлена переменная окружения <envar>EMAIL</envar>, то будет использована она.</para></listitem>
	<listitem><para id="x_47">Mercurial использует локальное имя пользователя и хоста в системе, чтобы создать конечное имя. Так как часто полученное имя малополезно, то будет выведено предупреждение.</para></listitem>
      </orderedlist>
      <para id="x_48">Если все варианты поиска завершились неудачно, Mercurial выведет сообщение об ошибке и не позволит создать коммит, пока вы не укажете имя пользователя.</para>
      <para id="x_49">Переменная <envar>HGUSER</envar> и опция <option role="hg-opt-commit">-u</option> в команде <command role="hg-cmd">hg commit</command> должны использоватся для <emphasis>изменения</emphasis> стандартного способа выбора имени. Для нормальной эксплуатации наиболее простой и надежный путь: установить имя в файле <filename role="special">.hgrc</filename>. Подробности смотри ниже.</para>
      <sect3 id="sec:tour-basic:username">
	<title>Создание файла конфигурации Mercurial</title>

	<para id="x_4a">Чтобы установить имя пользователя откройте свой любимый текстовый редактор и создайте файла <filename role="special">.hgrc</filename> в домашней директории. Mercurial будет использовать этот файл для поиска персональных настроек. Первоначальное содержание этого файла должно выглядить примерно так.</para>

	<tip>
	  <title><quote>Домашняя директория</quote> в Windows</title>

	  <para id="x_716">Домашний каталог, на английской установке Windows это, как правило, папка <filename>C:\Documents and Settings\&lt;имя пользователя&gt;</filename>. Вы можете узнать точное название вашей домашней директории, открыв окно командной строки и выполнив следующую команду.</para>

	  <screen><prompt>C:\></prompt> <userinput>echo %UserProfile%</userinput></screen>
	</tip>

	<programlisting># This is a Mercurial configuration file.
[ui]
username = Firstname Lastname &lt;email.address@example.net&gt;</programlisting>

	<para id="x_4b">Строка <quote><literal>[ui]</literal></quote> обьявляет <emphasis>секцию</emphasis> конфигурационного файла. Вы можете прочитать <quote><literal>username = ...</literal></quote> как <quote>установить значение переменной <literal>username</literal> в секции <literal>ui</literal></quote>. Секции продолжаются до начала новых секций. Пустые строки и строки, начинаюшиеся с <quote><literal>#</literal></quote> игнорируются.</para>
      </sect3>

      <sect3>
	<title>Выбор имени пользователя</title>

	<para id="x_4c">Вы можете использовать любой текст в качестве значения <literal>username</literal>, так как эта информация предназначена для других людей, а не для интерпретации Mercurial'ом. В примере выше для этого использовалось распространенное соглашение: комбинация имени и адреса электронной почты.</para>
	<note>
	  <para id="x_4d">Встроенный веб-сервер Mercurial обфускцирует адреса электронной почты для затруднения работы утилит сбора адресов, которые используют спамеры. Это уменьшает вероятность того, что вы начнете получать больше спама, если опубликуете репозиторий Mercurial в сети.</para></note>
      </sect3>
    </sect2>
    <sect2>
      <title>Описание ревизии</title>

      <para id="x_4e">Когда мы фиксируем изменения, Mercurial переводит нас в текстовый редактор, чтобы ввести комментарий, описывающее модификации, которые мы внесли в этом наборе изменений. Такое описание называется <emphasis>сообщением об изменениях</emphasis> (описанием изменений, описанием ревизии). Это будет записью для читателей о том, что мы сделали и почему, и будет выводиться при выполнении команды <command role="hg-cmd">hg log</command> после того, как мы закончим публикацию ревизии.</para>

       &interaction.tour.commit;

      <para id="x_4f">Редактор, который откроется при выполнении команды <command role="hg-cmd">hg commit</command>, будет содержать пустую строку и несколько строк, начинающихся с <quote><literal>HG:</literal></quote>.</para>

    <programlisting>
This is where I type my commit comment.

HG: Enter commit message.  Lines beginning with 'HG:' are removed.
HG: --
HG: user: Bryan O'Sullivan &lt;bos@serpentine.com&gt;
HG: branch 'default'
HG: changed hello.c</programlisting>

      <para id="x_50">Mercurial игнорирует строки, начинающиеся с <quote><literal>HG:</literal></quote>. Он использует их только для того, чтобы сообщить нам, изменения в каких файлах он запишет. Редактирование или удаление этих строк ни на что не повлияет.</para>
    </sect2>
    <sect2>
      <title>Написание хорошего сообщения к коммиту ревизии</title>

      <para id="x_51">Команда <command role="hg-cmd">hg log</command> по умолчанию выводит только первую строку описания изменений. Поэтому комментарий лучше написать так, чтобы первая строка была отделена. Вот хороший пример плохого комментария:</para>

      <programlisting>
changeset:   73:584af0e231be
user:        Censored Person &lt;censored.person@example.org&gt;
date:        Tue Sep 26 21:37:07 2006 -0700
summary:     include buildmeister/commondefs. Add exports.</programlisting>

      <para id="x_52">Для оставшейся части описания ревизии нет жестких правил. Сам Mercurial не обрабатывает и не заботится о содержимом сообщения об изменениях, хотя в вашем проекте могут быть правила, предписывающие определённое форматирование.</para>
      <para id="x_53">Моё личное предпочтение &emdash; короткие, но содержательные комментарии, которые сообщают мне то, чего я не могу выяснить при беглом взгляде на вывод команды <command role="hg-cmd">hg log --patch</command>.</para>
      <para id="x_55">Если мы выполним команду <command role="hg-cmd">hg commit</command> без каких-либо аргументов, запишутся все изменения, которые мы сделали, как сообщил <command role="hg-cmd">hg status</command> и <command role="hg-cmd">hg diff</command>.</para>

      <note>
	<title>Сюрприз для пользователей Subversion</title>

	<para id="x_717">Если мы явно не укажем имена файлов для ревизии, <command role="hg-cmd">hg commit</command> как и любая другая команда Mercurial будет действовать для всего рабочего каталога репозитория. Учтите это, если вы переходите из мира Subversion или CVS, где подобная команда работает только для текущего каталога и его подкаталогов.</para>
      </note>
    </sect2>

    <sect2>
      <title>Отмена публикации ревизии</title>

      <para id="x_54">Если вы передумаете публиковать изменения во время редактирования комментария, просто выйдите из редактора без сохранения изменяемого файла. Это не вызовет изменений ни в репозитории, ни в рабочем каталоге.</para>
    </sect2>

    <sect2>
      <title>Полюбуемся на наше творение</title>

      <para id="x_56">Закончив публикацию ревизии, мы можем воспользоваться командой <command role="hg-cmd">hg tip</command> для показа только что созданного набора изменений. Вывод этой команды похож на вывод команды <command role="hg-cmd">hg log</command>, но отображает только последнюю версию в репозитории.</para>

      &interaction.tour.tip;

      <para id="x_57">Мы называем последнюю ревизию <emphasis>конечной</emphasis> (или верхней) ревизией или просто <emphasis>главной</emphasis>.</para>

      <para id="x_684">Кстати, команда <command role="hg-cmd">hg tip</command> принимает многие из опций команды <command role="hg-cmd">hg log</command>. Так, например, <option role="hg-opt-global">-v</option> означает <quote>более подробно</quote>, <option role="hg-opt-tip">-p</option> &emdash; <quote>показать патч</quote>. Использование <option role="hg-opt-tip">-p</option> для показа патча является еще одним примером последовательного подхода к именованию опций.</para>
    </sect2>
  </sect1>

  <sect1>
    <title>Распространение изменений</title>

    <para id="x_58">Ранее мы упоминали, что репозитории в Mercurial самодостаточны. Это значит, что только что созданный набор изменений существует лишь в нашем репозитории <filename class="directory">my-hello</filename>. Давайте рассмотрим несколько способов, которыми мы можем распространить это изменение в другие репозитории.</para>

    <sect2 id="sec:tour:pull">
      <title>Получение (вытягивание) изменений из другого репозитория</title>

      <para id="x_59">Для начала клонируем наш исходный репозиторий <filename class="directory">hello</filename>, в котором нет последнего изменения, только что нами опубликованного. Назовём наш временный репозиторий <filename class="directory">hello-pull</filename>.</para>

      &interaction.tour.clone-pull;

      <para id="x_5a">Мы будем использовать команду <command role="hg-cmd">hg pull</command>, для получения изменений из <filename class="directory">my-hello</filename> в <filename class="directory">hello-pull</filename>. Однако вытягивание вслепую неизвестных изменений в репозиторий может быть пугающей перспективой. Mercurial позволяет узнать с помощью команды <command role="hg-cmd">hg incoming</command>, какие изменения команда <command role="hg-cmd">hg pull</command> <emphasis>вытянет</emphasis> в репозиторий без реального применения изменений.</para>

      &interaction.tour.incoming;

      <para id="x_5c">Получение изменений в репозиторий означает выполнение команды <command role="hg-cmd">hg pull</command> и указание ей, из какого репозитория следует вытягивать.</para>

      &interaction.tour.pull;

      <para id="x_5d">Как видно из вывода команды <command role="hg-cmd">hg tip</command> до и после, мы успешно вытянули изменения в наш репозиторий. Тем не менее, вытягивание изменений в Mercurial отделено от обновления рабочей директории. Остается один шаг до того, как мы увидим изменения в рабочем каталоге.</para>

      <tip>
	<title>Вытягивание конкретных изменений</title>

	<para id="x_5b">Вполне возможно, что из-за задержки между выполнением команд <command role="hg-cmd">hg incoming</command> и <command role="hg-cmd">hg pull</command>, вы можете увидеть не все ревизии, которые будут добавлены из другого репозитория. Предположим, вы тянете изменения из репозитория где-то в сети. Пока вы смотрите вывод <command role="hg-cmd">hg incoming</command>, перед тем как вытащить изменения, кто-то может что-то совершить в удаленном репозитории. То есть можно вытянуть больше изменений, чем вы видели при использовании <command role="hg-cmd">hg incoming</command>.</para>

	<para id="x_718">Если вы хотите получить именно те изменения, которые были указаны в <command role="hg-cmd">hg incoming</command>, или вам требуется некоторое подмножество изменений, просто укажите id ревизии, которую хотите получить, например <command>hg pull -r7e95bb</command>.</para>
      </tip>
    </sect2>

    <sect2>
      <title>Обновление рабочего каталога</title>

      <para id="x_5e">До сих пор мы говорили о связи между репозиторием и его рабочим каталогом. Команда <command role="hg-cmd">hg pull</command>, которую мы выполнили в <xref linkend="sec:tour:pull"/>, вытянула изменения в наш репозиторий. Но если проверить, в рабочем каталоге нет ни следа этих изменений. Это потому, что <command role="hg-cmd">hg pull</command> не трогает (по умолчанию) рабочий каталог. Для применения изменений мы используем команду <command role="hg-cmd">hg update</command>.</para>

      &interaction.tour.update;

      <para id="x_5f">Может показаться странным то, что <command role="hg-cmd">hg pull</command> не обновляет рабочий каталог автоматически. На самом деле этому есть веская причина: вы можете использовать <command role="hg-cmd">hg update</command>, для обновления рабочего каталога до состояния, в котором он был в <emphasis>любой ревизии</emphasis> в истории репозитория. Если бы вы обновили рабочий каталог до старой версии &emdash; например, чтобы отыскать причину ошибки, &emdash; а затем выполнили бы <command role="hg-cmd">hg pull</command>, которая обновляет рабочий каталог автоматически до новой версии, вы были бы ужасно недовольны этим.</para>

      <para id="x_60">Однако, так как вытягивание с последующим обновлением является распространенным явлением, Mercurial позволяет вам совместить их передачей команде <command role="hg-cmd">hg pull</command> ключа <option role="hg-opt-pull">-u</option>.</para>

      <para id="x_61">Если вы снова посмотрите на вывод команды <command role="hg-cmd">hg pull</command> в <xref linkend="sec:tour:pull"/>, когда мы выполнили её без <option role="hg-opt-pull">-u</option>, вы увидите, что в конце вывода было полезное напоминание о необходимости явного действия для обновления рабочего каталога.</para>

      <para id="x_62">Чтобы узнать, какая ревизия у рабочего каталога, используйте команду <command role="hg-cmd">hg parents</command>.</para>

      &interaction.tour.parents;

      <para id="x_63">Если вы снова взглянете на <xref linkend="fig:tour-basic:history"/>, вы увидите стрелки, соединяющие между собой каждую последующую ревизию. Вершина, <emphasis>из</emphasis> которой в каждом случае ведёт стрелка, &emdash; родитель, а та вершина, <emphasis>куда</emphasis> стрелка ведёт, &emdash; потомок. Аналогично, у рабочего каталога есть родитель &emdash; это набор изменений, который содержится в данный момент в рабочем каталоге.</para>

      <para id="x_64">Чтобы обновить рабочий каталог до конкретной ревизии, передайте номер или идентификатор ревизии команде <command role="hg-cmd">hg update</command>.</para>

      &interaction.tour.older;

      <para id="x_65">Если вы опустите явное указание ревизии, <command role="hg-cmd">hg update</command> обновит до верхней ревизии, как видно в примере выше при втором вызове <command role="hg-cmd">hg update</command>.</para>
    </sect2>

    <sect2>
      <title>Передача (проталкивание) изменений в другой репозиторий</title>

      <para id="x_66">Mercurial позволяет передать изменения в другой репозиторий из репозитория, в котором мы в данный момент находимся. Как с примером <command role="hg-cmd">hg pull</command> выше, создадим временный репозиторий для передачи в него наших изменений.</para>

      &interaction.tour.clone-push;

      <para id="x_67">Команда <command role="hg-cmd">hg outgoing</command> сообщает нам об изменениях, которые будут переданы в другой репозиторий.</para>

      &interaction.tour.outgoing;

      <para id="x_68">И команда <command role="hg-cmd">hg push</command> вызывает настоящую передачу.</para>

      &interaction.tour.push;

      <para id="x_69">Как и <command role="hg-cmd">hg pull</command>, команда <command>hg push</command> не обновляет рабочую директорию репозитория, в который передаются изменения. (В отличие от <command role="hg-cmd">hg pull</command>, у <command>hg push</command> нет ключа <literal>-u</literal>, который обновлял бы рабочую директорию другого репозитория). Эта асимметрия является преднамеренной: репозиторий в который мы передаём изменения может находиться на удаленном сервере и распределяться между несколькими людьми. Если бы нам пришлось обновить свой рабочий каталог в то время как кто-то работал в нём, его работа была бы нарушена.</para>

      <para id="x_6a">Что же произдойдёт, если мы попробуем получить или передать изменения, а в принимающем репозитории они уже есть? Ничего особенного.</para>

      &interaction.tour.push.nothing;
    </sect2>

    <sect2>
      <title>Размещение по умолчанию</title>

      <para id="x_719">Когда мы клонируем репозиторий, Mercurial записывает расположение репозитория из которого мы делали клон в файле <filename>.hg/hgrc</filename> нового репозитория. Если мы не будем указывать место для <command>hg pull</command> (откуда) или для <command>hg push</command> (куда), эти команды будут использовать это место в качестве репозитория по умолчанию. Команды <command>hg incoming</command> и <command>hg outgoing</command> делают то же самое.</para>

      <para id="x_71a">Если вы откроете файл <filename>.hg/hgrc</filename> в текстовом редакторе, вы увидите содержимое похожее на следующее.</para>

      <programlisting>[paths]
default = http://www.selenic.com/repo/hg</programlisting>

      <para id="x_71b">Возможно &emdash; и часто полезно &emdash; чтобы путь по умолчанию для <command>hg push</command> и <command>hg outgoing</command>, отличался от пути для <command role="hg-cmd">hg pull</command> и <command>hg incoming</command>. Мы можем так сделать, добавив запись <literal>default-push</literal> в секцию <literal>[paths]</literal> файла <filename>.hg/hgrc</filename>.</para>

      <programlisting>[paths]
default = http://www.selenic.com/repo/hg
default-push = http://hg.example.com/hg</programlisting>
    </sect2>

    <sect2>
      <title>Распространение изменений по сети</title>

      <para id="x_6b">Команды, которые мы затронули в нескольких предыдущих разделах, не ограничиваются работой с локальными репозиториями. Любая из них работает таким же способом и через сеть &emdash; просто укажите команде URL вместо локального пути.</para>
	
      &interaction.tour.outgoing.net;

      <para id="x_6c">В следующем примере мы могли бы увидеть, какие изменения мы можем передать в удалённый репозиторий, но в репозитории, очевидно, не разрешён приём изменений от анонимных пользователей.</para>

      &interaction.tour.push.net;
    </sect2>
  </sect1>

  <sect1>
    <title>Начало нового проекта</title>

    <para id="x_71c">Начать новый проект так же просто, как и использовать уже существующий. Команда <command>hg init</command> создает новый, пустой репозиторий Mercurial.</para>

    &interaction.ch01-new.init;

    <para id="x_71d">Это просто создаст репозиторий с именем <filename>myproject</filename> в текущем каталоге.</para>

    &interaction.ch01-new.ls;

    <para id="x_71e">Можно сказать, что <filename>myproject</filename> это репозиторий Mercurial, потому что он содержит каталог <filename>.hg</filename>.</para>

    &interaction.ch01-new.ls2;

    <para id="x_71f">Если мы хотим добавить существующие файлы в репозиторий, мы копируем их внутрь рабочей директории, и с помощью команды <command>hg add</command> сообщаем Mercurial, что нужно начинать за ними следить.</para>

    &interaction.ch01-new.add;

    <para id="x_720">После того как мы убедились, что проект выглядит хорошо, мы публикуем наши изменения.</para>

    &interaction.ch01-new.commit;

    <para id="x_721">Старт нового проекта с Mercurial займёт всего несколько мгновений, и это является частью его привлекательности. Контроль версий стал сейчас настолько простым, что мы можем его использовать даже в маленьких проектах, в которых, возможно, не использовали бы более сложные инструменты.</para>
  </sect1>
</chapter>

<!--
local variables: 
sgml-parent-document: ("00book.xml" "book" "chapter")
end:
-->
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.