Эта статья устарела.
Эта статья написана для услуги Виртуальный хостинг, которая считается устаревшей с 1 июня 2019 года.
Актуальную услугу хостинга можно заказать на нашем сайте netangels.ru/hosting
В данной статье рассмотрено использование СКВ Mercurial на хостинге. Система контроля версий Mercurial поможет управлять разработкой и поддержкой проектов.
Mercurial - это распределенная система контроля версий. Исторически более “традиционным” подходом к системам контроля версий был подход с использованием централизованных систем, например, Subversion.
Как следует из определения, фундаментальным отличием Mercurial от централизованных систем контроля версий является именно распределенность, или отсутствие единого центрального репозитория. Рассмотрим на примере Subversion и Mercurial разницу в централизованном и распределенном подходах в системах контроля версий.
Как происходит работа разработчика с репозиторием в Subversion? Разработчик запрашивает из центрального репозитория текущий срез (“рабочую копию”) кода и приступает к работе с ней. Завершив внесение каких-либо исправлений в код, которые представляют собой логически завершенное изменение разрабатываемого программного обеспечения, разработчик выполняет так называемый “коммит” - транзакцию внесения сделанных изменений в центральный репозиторий, после чего текущей “рабочей копией” (trunk в терминах Subversion) репозитория становится код с внесенными в него на этапе коммита исправлениями.
В Mercurial работа разработчика с репозиторием заметно отличается. Допустим, новый разработчик получил доступ к репозиторию Mercurial, находящемуся на проекта (получение может быть не только с репозитория на общем сервере, но об этом ниже). Он выполняет операцию клонирования репозитория, при этом помимо текущей рабочей копии он получает в свое распоряжение полную копию всего репозитория с историей каждого файла. Разработчик вносит определенные изменения в код, наступает время сохранить изменения в репозитории, и он выполняет “коммит”, но транзакция вносится в его локальную копию репозитория. Для передачи внесенных им в локальный репозиторий правок в репозиторий на сервере необходимо выполнить еще одну команду - передачу изменений между локальным и удаленным репозиториями.
На первый взгляд может показаться, что такой подход заставляет выполнять излишние действия для внесения изменений, а наличие полной копии репозитория может запутать. В действительности же это совсем не так. Рассмотрим случаи, когда наличие локального репозитория дает явные преимущества перед центральным репозиторием:
Возможность совершать “мелкие” коммиты: допустим, разработчик сделал какое-то изменение в коде, которое, на его взгляд, заслуживает того, чтобы сделать для него коммит, но сделанные правки еще нельзя назвать целостным изменением в коде проекта, поэтому коммит в основной общедоступный репозиторий нежелателен. В случае с Subversion разработчик вынужден отказываться от выполнения такого коммита и не имеет возможности делать какие-то атомарные изменения в своем рабочем коде с возможностью легко откатиться. Отчасти эту проблему можно решить созданием отдельной ветки (branch) кода, но это далеко не всегда оправдано. В случае распределенных систем контроля версий (Mercurial) разработчик просто делает столько коммитов в локальный репозиторий, сколько ему нужно (при необходимости делая откаты), то есть имеет большую свободу для проб и экспериментов. Когда разработчик решает, что внесенные изменения уже представляют целостную модификацию рабочего проекта, он выполняет одну транзакцию, копируя все сделанные им изменения из локального репозитория в общий.
Отсутствие необходимости иметь постоянный доступ к основному репозиторию: вне зависимости от доступа к сети в случае с распределенными системами контроля версий разработчик имеет в своем распоряжении полноценную копию репозитория с возможностью делать коммиты, откаты, просматривать историю изменений, создавать новые ветки и т.п.
Распределенность также подразумевает необязательность основного репозитория. Допустим, на сервере располагается общедоступный репозиторий, с которым работают несколько разработчиков. Один из них начал работу по реализации какого-то нового функционала в проекте, но изменение еще не завершено и вносить его в общедоступный репозиторий нежелательно. Разработкой заинтересовался другой разработчик, готовый прийти первому на помощь в ее реализации. В случае с распределенной системой контроля версий (Mercurial) для того чтобы второму разработчику получить наработки первого (которых еще нет в общем репозитории), ему достаточно выполнить запрос на получение изменений из репозитория первого разработчика в свой локальный репозиторий. Или, как вариант, инициатива может исходить от первого разработчика, и он может выполнить передачу необходимых изменений в репозиторий второго разработчика вместо основного репозитория. По мере дальнейшей совместной работы над новым функционалом оба разработчика периодически передают между своими репозиториями сделанные изменения. Когда работа над кодом завершена, одному из них достаточно просто выполнить транзакцию по передаче всех накопленных изменений в общий репозиторий. При подобной модели работы “основной” репозиторий может вообще отсутствовать, и все изменения могут передаваться между репозиториями разработчиков по аналогии со схемой передачи информации в p2p (peer-to- peer) сетях.
Разработчикам, имеющим опыт работы с Subversion, принципы взаимодействия с Mercurial покажутся во многом знакомыми. Также как и в Subversion, в Mercurial для выполнения всех действий с репозиторием используется одна программа - hg. Для выполнения каждого действия с репозиторием этой программе передается определенная команда, при необходимости дополненная соответствующими параметрами. Ниже приведены некоторые основные команды для работы с репозиториями.
hg init
Выполнение этой команды в текущем (пустом) каталоге создаст в нем пустой Mercurial репозиторий. Также может быть выполнена как hg init имя_каталога, при этом создаст необходимый каталог и инициализирует пустой репозиторий в нем.
hg clone исходный_репозиторий репозиторий-клон
Создает копию репозитория в указанном каталоге. Может использоваться как для создания локальной копии удаленного репозитория, так и для создания копии локального репозитория для реализации какой-либо новой возможности (в некоторых случаях наличие отдельного репозитория может быть предпочтительней отдельной ветки в рамках одного репозитория).
hg pull репозиторий-источник
Pull - дословно “утянуть”, “стянуть”. Выполненная в каталоге с локальным репозиторием, эта команда скопирует с репозитория-источника все недостающие в локальном репозитории изменения. Если репозиторий был клонирован с другого, то команду можно сократить до hg pull, при этом в качестве источника будет взят тот же репозиторий, что и при предыдущем получении изменений. Важно понимать, что выполнение этой команды только обновляет историю изменений в репозитории, рабочая копия при этом остается нетронутой. Для ее актуализации служит следующая команда.
hg update
Выполняет актуализацию рабочей копии кода до последней версии. Обычно выполняется после получения набора изменений с другого репозитория (hg pull). Также может быть использована для получения рабочей копии по состоянию на какую-либо указанную ревизию.
hg commit
Вносит модификации, сделанные в рабочей копии, в репозиторий, создавая отдельную ревизию (версию). По умолчанию в репозиторий будут внесены изменения для всех файлов, находящихся под управлением mercurial; изменения только для некоторых файлов можно занести в репозиторий, указав их имена: hg commit файл1 файл2 …
hg push репозиторий-получатель
Обратная к hg pull команда. Выполняет передачу в репозиторий-получатель недостающих по сравнению с локальным репозиторием наборов изменений.
Добавить файлы в репозиторий (фактически будут добавлены в репозиторий при выполнении последующей команды hg commit):
hg add файл1 файл2 файл3...
Удалить файлы из репозитория (история изменений для указанных файлов в репозитории сохраняется, файлы также удаляются из текущей рабочей копии):
hg remove файл1 файл2 файл3...
Переименование/перемещение файлов, находящихся под управлением mercurial, выполняется следующими командами:
hg rename старое_имя новое_имя
аналог:
hg mv старое_имя новое_имя
Важно помнить, что простое переименование файла средствами операционной системы нежелательно, т.к. с точки зрения mercurial это будет означать просто исчезновение одного из находящихся под контролем файла. Вышеуказанной командой мы как раз даем знать системе управления версиями, что сменилось имя определенного файла, при этом вся соответствующая история изменений также будет корректно привязана к переименованному файлу.
hg status
Покажет состояние текущей рабочей копии. Полезно для просмотра того, какие файлы изменились со времени последней актуализации рабочей копии, какие добавились и т.п. Выводит список файлов с односимвольным индикатором состояния файла. Наиболее часто встречающиеся:
M - файл изменен (файл в рабочей копии отличается от файла в репозитории)
A - файл добавлен (при выполнении команды hg commit будет фактически внесен в репозиторий)
R - файл удален (при следующем выполнении hg commit будет помечен в репозитории как удаленный для последующих ревизий)
! - файл находится под управлением mercurial, но не найден в рабочей копии (например, был ошибочно удален средствами операционнной системы)
? - файл присутствует в рабочей копии, но не находится под управлением mercurial (для внесения такого файла в репозиторий надо выполнить hg add имя_файла)
Зачастую в каталогах проекта могут появляться какие-то файлы, которые нежелательно отдавать на попечение системы контроля версий. Например, к таким файлам могут относиться различные временные файлы, создаваемые текстовым редактором или компилятором. Такие файлы можно просто не включать в репозиторий, но при каждом выполнении команды hg status будет выводиться их список с пометкой “?”. Чтобы избежать такого поведения, существует специальный список файлов-исключений - файлов, которые должны игнорироваться mercurial, хотя и могут находиться в каталоге рабочей копии. Такой файл носит имя .hgignore и должен располагаться в корневом каталоге репозитория. Формат файла следующий:
# comments
syntax: glob
*.bak
*.tmp
syntax: regexp
\.bak$
\.tmp$
Строки, начинающиеся со знака “#”, являются комментариями. Строка, начинающаяся со слова “syntax:”, означает указание на используемый далее в тексте тип описаний. Может принимать два различных значения: glob - в этом случае файлы для исключения описываются масками по аналогии с используемыми в операционных системах (символ ‘*’ означает любое количество любых символов, символ ‘?’ означет строго один любой символ); regexp - в этом случае для описаний используются регулярные выражения (формат которых аналогичен используемым в Perl).
Общепринятой практикой является создание файла .hgignore сразу же после создания репозитория и включение этого файла в самый первый набор изменений (“коммит”).
Для всех вышеперечисленных случаев, где указывается удаленный репозиторий, подразумевается его доступность хотя бы по одному из поддерживаемых mercurial транспортных протоколов. Репозитории могут быть указаны следующими способами:
локальная/файловая/система или file://локальная/файловая/система - используется в случае, когда имеем дело с репозиторием на локальном компьютере.
http://пользователь@хост:порт/путь и https://пользователь@хост:порт/путь - используется для доступа к репозиториям, обслуживаемым mercurial, запущенным в режиме веб-сервера.
ssh://пользователь@хост:порт/путь - используется для доступа к репозиторию по протоколу ssh. На системе, с которой устанавливается ssh-сессия, также должен быть установлен mercurial.
static-http://пользователь@хост:порт/путь - используется для доступа к репозиториям, выложенным на веб-сервер в виде простого каталога. Не требует наличия дополнительного программного обеспечения или настройки. Доступ в таком случае возможен только на чтение.
Система контроля версий mercurial доступна для всех клиентов NetAngels, обслуживающихся на тарифных планах хостинга за исключением ТП “Базовый”. Доступ к репозиторям может быть организован следующими способами:
Для ТП “Стандарт” - доступ по протоколу ssh. Публичный доступ к репозиторию на чтение может быть предоставлен с использованием протокола static-http. Для этого необходимо лишь поместить репозиторий внутрь дерева каталогов любого из доступных сайтов.
Для ТП “Профи” или VDS доступ может быть организован любым из поддерживаемых mercurial способов удаленной работы с репозиторием.
Допустим, мы начинаем работу над каким-либо проектом.
Создаем пустой локальный репозиторий.
hg init myproject
Переходим в созданный каталог репозитория myproject, создаем список исключений .hgignore с масками имен файлов для исключений, помечаем его как находящийся под управлением mercurial и делаем первый коммит - внесение изменений в репозиторий.
hg add .hgignore
hg commit -m 'самое первое изменение'
При выполнении команды commit добавлен комментарий, который будет отображаться в истории изменений. Если выполнить команду как hg commit без добавления комментария, откроется окно текстового редактора для описания сделанных изменений в нем.
Создадим копию текущего репозитория на хостинге.
hg clone . ssh://uXXXX@uXXXX.netangels.ru/myproject
Здесь “.” (точка) указывает на текущий каталог, то есть наш репозиторий. Далее идет указание удаленного репозитория: протокол ssh, имя пользователя uXXXX (логин ssh для клиента хостинга NetAngels), имя хоста, каталог репозитория.
Создадим в рабочей копии несколько файлов: file1.txt, file2.txt, file3.txt. Пометим файлы как находящиеся под контролем mercurial и сделаем коммит для их фактического добавления в репозиторий.
hg add
hg commit
Для распространения изменений, сделанных в локальном репозитории на удаленный, необходимо выполнить команду push (“толкать”):
hg push ssh://uXXXX@uXXXX.netangels.ru/myproject
Теперь удаленный репозиторий содержит все сделанные локально изменения и может быть использован для клонирования либо обновления существующих копий репозиториев у других разработчиков.
Для дальнейшего ознакомления могут быть полезны следующие ресурсы:
TortoiseHg - сборка Mercurial под ОС Windows, включающая в себя расширение для Windows Explorer (“Проводник” Windows), позволяющее выполнять работу с репозиторием прямо из контекстного меню (скриншот).