Думаю, почти все читающие знают, что такое Mercurial — это распределённая система контроля версий, для исходного кода и других (преимущественно текстовых) файлов. Многие ей пользуются, и знают основные команды, как то удаление/добавление файлов, создание коммита и отправка локальных изменений в другие репозитории. Однако, Mercurial имеет множество не столь известных функций и команд, которые часто достаточно полезны и удобны. Некоторые из них можно использовать сразу после установки по-умолчанию, некоторые нужно включить в настройках, а для других может потребоваться скачать дополнительное расширение.
Краткий список того, о чём пойдёт речь в статье:
- hg serve (hgweb) — встроенный веб-сервер
- расширения pager, progress и color
- hg [c]record — выбор отдельных изменений для коммита
- revsets и filesets — поиск коммитов и файлов с запросами любой сложности
- hg evolve — Changeset Evolution или же «изменяемая история»
hg serve (hgweb)
В стандартную поставку Mercurial входит веб-сервер, который позволяет быстро просмотреть репозиторий с удобным интерфейсом в любом браузере — для этого достаточно, находясь в папке с репозиторием, выполнить hg serve
, и зайти на localhost:8000
(стандартный порт — 8000). Так можно просматривать почти всю информацию, которая доступна через обычный интерфейс командной строки. При этом с другого компьютера по сети можно использовать hg clone
с адресом запущенного hgweb для клонирования.
Конечно, было бы странно, если бы веб-сервер можно было использовать только для этого — и это не так. Hgweb можно настроить так, чтобы он обрабатывал сразу несколько репозиториев, например из одной папки, а также поставить перед ним nginx или другой сервер (вариантов коммуникации хватает — обычный http через порт, или к примеру wcgi). Тонкости конфигурации рассмотрены в частности в официальной вики Mercurial. Важная функция, которой иногда не хватает в hgweb — авторизация пользователей и права на чтение/запись — также может быть реализована установкой и настройкой дополнительного frontend сервера. Например, я использую для этого обычную http-авторизацию в nginx, который запрещает любой неавторизованный доступ к приватным репозиториям, а также push в публичные.
Что касается внешнего вида, то в комплекте поставляется несколько тем на выбор, по-умолчанию используется «paper».
Примеры: selenic.com/hg — официальный репозиторий, hg.python.org — репозитории Python, hg.aplavin.ru — мои (в основном) репозитории.
Расширения pager, progress, color
Эти расширения входят в установку Mercurial, и для использования достаточно включить их в настройках. Для этого нужно добавить в файл ~/.hgrc
секцию расширений:
[extensions]
pager =
progress =
color =
(да, после знаков равенства ничего нет). Эти расширения делают работу с CLI-интерфейсом несколько более удобной: выводы многих команд становятся цветными, во время длительных операций выводится прогрессбар, а длинные простыни команд вроде hg log
можно прокручивать — они открываются в стандартном pager'e (обычно это less
). К сожалению, страницы помощи (hg help
) открываются как и раньше, и для их удобного просмотра нужно вручную дописывать | less
. Эти расширения не включены по-умолчанию, как говорит автор Mercurial, из-за иногда встречающихся неожиданных проблем с ними, в частности на Windows.
hg [c]record
Часто после долгого редактирования исходников бывает удобнее разбить внесённые изменения на несколько коммитов, а не делать один большой. В стандартной поставке Mercurial для этого есть расширение record
, которое достаточно просто включить в настройках для использования. После этого собственно для выбора изменений нужно будет выполнить hg record
и в текстовом интерфейсе выбрать нужные части.
Однако, это расширение не очень удобное и подходит только для эпизодических правок. Если вы пользуетесь такой функцией чаще, лучше скачать и подключить другое расширение, не из стандартного комплекта: crecord. Оно предоставляет достаточно удобный для использования псевдографический интерфейс (пример от его автора: ). Конечно, есть и полностью графические утилиты для этого (мне, например, понравилась qct, написанная на Qt), но для простых правок прямо «на месте» в консоли crecord вполне удобен.
revsets
Mercurial использует язык запросов, который можно использовать для сколь угодно сложных критериев поиска коммитов, причём он поддерживается во всех командах, которые работают с коммитами (а скоро будет и в hgweb). Например, почти «классический» пример — есть некоторый коммит, в котором исправлен баг, и нужно найти релизы в которые этот багфикс попал. Предполагая, что для задания релизов используются теги (все проекты, которые видел, так и делают), такой запрос можно сформулировать как 'tag() and descendants(x)'
или 'tag() and x::'
(где x
— идентификатор коммита). То есть, если выполнить hg log 'tag() and x::'
, мы увидим все искомые релизы. Подробная информация о синтаксисе и всех имеющихся функциях — hg help revsets
или на официальном сайте.
filesets
Filesets представляет собой также язык запросов, аналогичный revsets, но для задания файлов (для соответствующих команд, которые работают с файлами). Используется он почти аналогично, только в начале нужно добавлять set:
, чтобы не было путаницы с обычными именами файлов. Что касается поддерживаемых функций, то они также есть в стадартной помощи: hg help filesets
.
Changeset Evolution
Расширение evolve — экспериментальное, которое сейчас разрабатывает (в основном) один из членов команды Mercurial. Оно экспериментальное из-за пока ещё окончательно не решённых вопросов с UI и производительностью в некоторых случаях, а не из-за недостатка стабильности (вообще говоря, часть кода, связанного с его функциями, находится в самом Mercurial, но не работает по-умолчанию). В частности, это расширение используется в самом официальном репозитории Mercurial.
Changeset Evolution при подключение не только добавляет новые команды, но и изменяет поведение стандартных (и из других расширений) — тех, которые каким-либо образом редактируют историю: commit --amend, rebase, histedit
и некоторые другие. При использовании evolve
никакие коммиты полностью не удаляются из репозитория (за исключением команды strip
, предназначенной как раз для полного удаления, которое всё же может пригодиться). Любое редактирование истории просто помечает более ненужные коммиты как удалённые (точнее, устаревшие — obsolete
), а новые коммиты — как заменившие их. Таким образом, всегда можно найти любую версию изменения, которая когда-то раньше существовала.
Также, из дополнительных получаемых «плюшек» — возможность редактирования изменений, уже отправленных в публичный репозиторий. Причём те, кто имеет его локальную копию, при загрузке новых изменений также получат информацию об удалённых (устаревших) коммитах и их локальных репозитории так же изменятся (при условии, конечно, что у них тоже включено это расширение). Без evolve
такого достить нельзя.
Заключение
Вообще, в Mercurial есть и другие «продвинутые» возможности, но в этой статье я постарался описать те из них, которые могут пригодиться многим пользователям, и которыми люди не пользуются часто из-за незнания. Также хотелось бы добавить, что в Mercurial очень строгая политика обратной совместимости — все вносимые изменения не затрагивают имеющуюся функциональность, а добавляют новую. Очень старая версия на сервере может работать с новым клиентом, и наоборот (разумеется, неподдерживаемые в старой версии функции работать не будут). Такая серьёзная обратная совместимость касается всех команд и функций, видимых пользователю, то есть внутреннее API может меняться (но без весомых причин этого тоже не делают).
Сам я использую Mercurial на базовом уровне уже несколько лет, а в этом году участвую в Google Summer of Code с проектом улучшения hgweb
. Попутно, общаясь с разработчиками, узнал и начал использовать в частности описанные в этой статье функции.
Автор: chersanya