Разработка → Hg Init: Часть 6. Архитектура репозиториев

перевод
Bobrovsky 6 декабря 2010 в 10:30 24,1k
Оригинал: Joel Spolsky
Это шестая, заключительная часть из серии Hg Init: Учебное пособие по Mercurial от Джоэля Спольски (Joel Spolsky). Предыдущие части:



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 хранится новый код и проводятся слияния с исправлениями ошибок.

Есть и другие применения нескольким репозиториям.

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


В больших сложно устроенных организациях вы можете комбинировать эти техники и настраивать цепочки репозиториев, вытягивающих изменения друг из друга. По мере того, как какой-то функционал проходит этапы тестирования и интеграции, он втягивается в репозитории по цепочке до тех пор, пока, наконец, не окажется в главном репозитории, хранящем код, который получают клиенты:



Проверь себя


Вот то, что вы должны уметь делать после прочтения данной части:
  1. Помечать старые версии и возвращаться к ним.
  2. Организовывать работу команды с двумя репозиториями (stable и dev).


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

Комментарий от переводчика:
Если вам, так же как и мне, интересно увидеть гуакамоле, то вот видео, в котором показан процесс приготовления этого блюда.

Проголосовать:
+45
Сохранить: