
- «Переобучение для пользователей Subversion»
- «Основы Mercurial»
- «Привыкаем работать в команде»
- «Исправляем ошибки»
- «Процесс слияния»

Mercurial позволяет очень гибко настроить репозитории. Плюс, так как слияния работают отлично и вы можете на них полагаться, можно иметь особые служебные репозитории в соответствии с требованиями процесса разработки в вашей команде.
Часть 6. Архитектура репозиториев
Наш рецепт становится все лучше:

Давайте приглядимся к номеру набора изменений:

Первая часть номера, 13, короткая и удобная. Проблема в том, что… на нее нельзя полагаться!
При независимой работе членов команды и осуществлении слияний эти короткие номера могу начать отличаться у разных членов команды:

Так что на практике я не могу сказать: «Хорошо, давайте выпускать версию, собранную из 13 набора изменений», потому что у сотрудников может быть разное представление о том, что является 13-тым набором. Вот почему есть еще и тот безумный шестнадцатеричный номер.

Этот шестнадцатеричный номер уникален во всех репозиториях и никогда не меняется.
То есть я могу сказать людям: «Эй, сегодня релиз! 1b03ab783b17-ый набор изменений!». Согласитесь, было бы неплохо иметь возможность дать этому набору имя?
Ну, у вас есть такая возможность. Такое имя называется тег (или таг, от англ. tag).

Давайте теперь взглянем на лог:

Обратите внимание, что само добавление тега к набору изменений является набором изменений. Этот набор изменений автоматически фиксируется в репозитории (коммитится). Так что теперь каждый раз, когда я хочу сослаться на ту версию кода, что мы выпустили, я могу использовать Version-1.0 вместо 1b03ab783b17.
Замдиректора спустился с 31-го этажа для того чтобы поучаствовать в офисной вечеринке по поводу выпуска новой версии и принес ящик достаточно дорогого на вид игристого вина. Стэн немного напился. Ну, не то, чтобы немного. Вообще-то, это было что-то невиданное. Стэн снял рубашку и, показывая всем свои мускулы и солидное пузо, пытался произвести впечатление на дам из отдела маркетинга. Он хвалился: «Я буду подтягиваться на лампах» (у нас в офисе используются длинные лампы дневного света). В общем, он подпрыгнул, схватился за светильник и, конечно же, оторвал его вместе с лампами и потолочной плиткой. Неудивительно, ведь светильник весом в примерно 4,5 килограмма висел на паре проволочек, а вес Стэна как раз в том самом популярном диапазоне 130-135 килограммов. Повсюду было битое стекло и куски звукоизолирующей плитки. Стэн упал прямо на копчик и начал жаловаться, что засудит компанию за небезопасные условия труда.
Остальные вернулись на рабочие места для работы над Guac 2.0.

Коммит:

Не стоит и говорить, что этот рецепт пока сомнителен. Его не тестировали, к примеру. И тут звонит клиент.
«Слишком солёно получается!», скулит клиент. И нет, он не желает подождать выхода версии 2.0 с исправлением ошибки.
К счастью, у нас есть тот тег. Я могу использовать
hg up
для перехода к любой версии в репозитории.
Теперь я могу исправить эту тупую проблему с солью:

Затем:

Mercurial напоминает мне, что мои действия создали новую голову. Теперь в репозитории две головы: версия 2.0, над которой я недавно работал, и версия, которую я только что закоммитил.

В данный момент я могу отдать версию с последними изменениями клиенту, пометить ее как 1.1, и продолжить работать с версией 2.0.

Но есть одна проблема… исправления про соль отсутствуют в версии 2.0. Как мне это исправить?


Ну вот. Я должен сделать слияние тегов. Это известный баг в Mercurial. Проблема в том, что теги в Mercurial — это просто файл с именем .hgtags, для которого тоже ведется контроль версий. Поэтому время от времени вам нужно вручную делать слияние разных версий файла .hgtags. В такой ситуации ваши действия просты… нужно всегда сохранять ОБЕ версии каждой строки в файле.

Описанный выше простой способ перейти к старой, помеченной версии годится, если вам нужно сделать лишь одно маленькое незапланированное изменение в выпущенном коде. Но правда в том, что в большинстве программных проектов такие ситуации возникают постоянно, а у Mercurial есть более надежный способ разобраться с ними.
Так что я сейчас отменю все изменения, сделанные после 1.0, верну репозиторий в состояние, которое у него было в момент выпуска 1.0, и затем смогу показать вам модный надежный способ исправлять баги существующих клиентов и параллельно работать над новой версией.

Идея в том, что вместо работы с одним репозиторием мы заведем два репозитория. Один репозиторий назовем stable, а второй — dev.
В репозитории stable хранится последняя мажорная версия кода, отправленная клиентам. Каждый раз, когда вам нужно срочно исправить баг, вы делаете это в stable. В нашем примере, все патчи для версии 1.0 попадут в stable.
Репозиторий dev — это то место, где ведется разработка следующей мажорной версии, то есть версии 2.0.
Как только вышла версия 1.0, я клонирую stable в dev:

Теперь у меня два идентичных репозитория:

Так как история в обоих репозиториях одинакова до 14-го набора изменений включительно, то Mercurial воспользуется "жёсткими ссылками" вместо того, чтобы делать две копии на диске. Поэтому операция
hg clone
выполняется быстро и дешево, а значит, вы можете без колебаний делать много-много клонов репозитория.Теперь начнем работать над guac в репозитории dev:

И исправим ту проблему с солью в репозитории stable:

Я помечу эту версию и выпущу ее как 1.1:

Теперь, время от времени, нам нужно втягивать изменения из stable в dev:

Вот что мы только что сделали:

И если вы можете понять, что нарисовано на этой безумной картинке, то с пониманием Mercurial у вас больше проблем не будет. Суть в том, что в репозиторий stable попадают только исправления ошибок, а в репозитории dev хранится новый код и проводятся слияния с исправлениями ошибок.
Есть и другие применения нескольким репозиториям.
- Вы можете настроить командные репозитории, в которых несколько человек вместе работают над каким-то новым функционалом. Когда они закончат и все сделанное будет работать правильно, вы протолкнете изменения из командного репозитория в главный репозиторий, и все увидят эти изменения.
- Вы можете настроить репозиторий для тестеров. Вместо того чтобы сразу проталкивать изменения в главный репозиторий, вы будете проталкивать изменения в репозиторий тестеров. Тестеры проверят изменения и когда (и если) изменения будут одобрены, вы сможете протолкнуть изменения из репозитория тестеров в главный репозиторий. При таком подходе главный репозиторий всегда будет содержать протестированный код.
- Так как у каждого разработчика свой репозиторий, то вы можете вытягивать на пробу экспериментальные изменения из репозитория товарища, не влияя на работу остальной команды.
В больших сложно устроенных организациях вы можете комбинировать эти техники и настраивать цепочки репозиториев, вытягивающих изменения друг из друга. По мере того, как какой-то функционал проходит этапы тестирования и интеграции, он втягивается в репозитории по цепочке до тех пор, пока, наконец, не окажется в главном репозитории, хранящем код, который получают клиенты:

Проверь себя
Вот то, что вы должны уметь делать после прочтения данной части:
- Помечать старые версии и возвращаться к ним.
- Организовывать работу команды с двумя репозиториями (stable и dev).
Что ж, так получилось, что мы дошли до конца пособия. Я даже близко не подобрался к тому, чтобы описать все возможности Mercurial, но есть достаточное число материалов для углубленного изучения. Есть книга, которая описывает все крайне подробно. И если у вас есть какие-либо вопросы, то я приглашаю вас на сайт Kiln Knowledge Exchange (это как StackOverflow, только для Kiln, и вопросы про Mercurial более чем приветствуются на этом сайте).
Комментарий от переводчика:
Если вам, так же как и мне, интересно увидеть гуакамоле, то вот видео, в котором показан процесс приготовления этого блюда.