Полезности Mercurial

в 15:20, , рубрики: commit, evolution, Extensions, Mercurial, mutable, version control, системы контроля версий, Системы управления версиями, метки: , , , , , ,

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

Краткий список того, о чём пойдёт речь в статье:

  • hg serve (hgweb) — встроенный веб-сервер
  • расширения pager, progress и color
  • hg [c]record — выбор отдельных изменений для коммита
  • revsets и filesets — поиск коммитов и файлов с запросами любой сложности
  • hg evolve — Changeset Evolution или же «изменяемая история»

logo

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. Оно предоставляет достаточно удобный для использования псевдографический интерфейс (пример от его автора: image). Конечно, есть и полностью графические утилиты для этого (мне, например, понравилась 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js