Table of Contents

Меркуриал и что с ним делать

Общее

Меркуриал - распределенная система управления версиями (DVCS). Написана на питоне и потому работает везде и легко расширяется. Лучший друг и помощник разработчика, который понимает что с ней можно делать.

Термин “распределенность” зачастую понимается неправильно. В данном случае это не означает отсуствие главной репо, а лишь то, что изначально работа ведется с локальной (обычно дочерней) репо и не для своего функционирования не требует доступности родительской. Меджу репо существуют зависимости в виде DAG, но для упрощения работы обычно ограничиваются древообразной структурой получаемой клонированием родительской. В целом же, “распределенность” больше относится к свободе перемещения changeset'ов в этой иерархии.

Нужно помнить, что любая DVCS система куда более мощный инструмент нежели их далекие предки в виде CVS и SVN (Preforce, clearcase etc), которые в силу функциональных ограничений и юзабилити использовались максимум как удаленный способ хранения “снимка” рабочей копии и доставки последних изменений в оную от других пользователей. В этом разрезе mercurial предоставляет свободу выбора наиболее подходящего конкретному процессу разработки workflow. Впрочем, эта же свобода является и камнем преткновения, причиной крутой learning curve.

Прямым следствием является необходимость подумать, прежде чем что то сделать. Еще раз - dvcs это не дропбокс и не расшареный каталог “с историей”. Нужно представлять что ты хочешь сделать в терминах истории и changeset'ов. Только этим можно достигнуть светлой стороны силы!)

Правила хорошего тона

Банальности, но все же.

Еще немножко о зависимостях

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

Для решения этой проблемы в меркуриале существует расширение для организации зависимостей между репами. С его помощью легко организовать репозиторий так, что клонировании или обновлении рабочей копии в соседний или вложенный каталог вытаскивались и зависимости из своих собственных репо. Причем зависимые репо даже не должны быть меркуриалом, т.к. поддерживаются svn, cvs и другие git'ы. Более того, этим же расширением достигается и другой, немаловажный момент, а именно - фиксация зависимых версий. Иными словами, при инициализации зависимости сохраняется конкретная ревизия, которую мы утянули и эта ревизия версифицируется вместе с содержимым главной репо. Таким образом а) мы не подверженны внезапным breaking changes когда сторонние разработчики внезапно обновляют зависимый проект. б) так же, при желании мы можем обновить зависимость до новой версии и убедится что это все будет работать. с) мы не храним своей локальной копии и все зависимости утягиваются прямиком из первоисточника.

Настройка

Бинарный билд для вашей платформы легко гуглится. В домашнем каталоге появляется файл конфигурации ( win - %USERDIR%\Mercurial.ini, linux - ~/.hg/hgrc ) В котором необходимо поправить следующее:

Базовые операции

Смотрите маны

Операции специфичные для DVCS

Помимо обычных операций, свойственных обычным системам контроля версий, в современных dvcs доступны новые, облегчающие работу разработчика операции. Вот некоторые из них.

Горизонтальные версии

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

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

Указанная функциональность обеспечивается посредством расширений: mq, pbranch, attic, shelf итп

Машина времени или манипуляции с историей

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

Светлой стороне силы DVCS доступна возможность избавится от подобных артефактов. Главным помощником разработчика в этом является встроенная ( пришедшая из git ) комманда rebase. С ее помощью можно, например, объединить все changeset'ы локального бранча и накатить их поверх tip'а. Или же, в процессе работы ( и серии коммитов ) над фичей, принять изменения и переместить все свои наработки поверх текущей версии. И еще много чего.

Более детальное объяснение см. в секции Advanced workflow.

Workflow

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

Поэтапный процесс

[ Production repository ] содержит от-tag'еные релизы. 
     ^ ^ ^ ^ ^ ^ ^ 
[ Staging/demo repository ] содержит пред-релизные версии для конечного тестирования, только из нее можно отправить версию в продакшен
     ^ ^ ^ ^ ^ ^ ^
   [ QA repository ] промежуточные результаты интеграции, версии для QA тима и автоматизированного тестирования
        ^ ^ ^ ^
      [ Dev repo ]  общий репозиторий текущей версии в разработке, с ней взаимодействуют только разработчики. Это место для стабильных версий.
      
  1. Продакшен - это доступная в любое время стабильная, протестированная итп версия, которую можно взять и отдать клиенту. Обновляется самым главным вручную по результатам из staging/demo.
  2. Staging/demo - протестрованная насколько можно, готовая к выкладыванию в боевые условия версия. Отсюда можно всегда взять нечто готовое, свежее и показать. (Что то вроде PTR.) Обновляется раз в сутки по результатам тестирования из QA репы и необходимости этого обновления (демонстрация, промежуточные-релизы итп)
  3. QA - собранная версия подготовленная для (автоматического) тестирования. В нее раз в сутки или по некоторому условию сливаются результаты работы из development репы. С ней работают тестеры.
  4. Dev - общие результаты работы ежедневно. Ест-но в ней не должно появлятся поломаных версий, т.е. коммит в нее производится только после удачной сборки и некоего минимального набора тестов.

Централизованная с побочным хранилищем (патчей)

Одна главная репа с отмечеными продакшен релизами и бранчами для минорных / мажорных версий. Пример - в главном бранче живет текущая живая версия, от нее отпочковываются по мере релизов мажорные и соответственно от мажорных - минорные версии. Готовые релизы помечаются тэгами в соответствующих бранчах. Дополнительно разработчики используют attic/mq/shelve расширение с отдельной общей репо для хранения и обмена патчами. Этим способом организуется возможность:

На PBranch

Совместная работа с унаследованной CVS / SVN репо

Работа с Patch Queue

С отслеживанием изменяемых snapshot'ов

Advanced workflow

Социальные сайты - репозитории

На примере bitbucket'а. Каковы преимущества по сравнению с home-brewed решением?

Ссылки по теме