суббота, 30 октября 2010 г.

Субботний вечер пропаганды маргинальных технологий: hgsubversion

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

Сегодня хотел немного затронуть тему распределенных систем контроля версий. На самом деле, эта тема достаточно популярно, просто больших компаниях приживается очень плохо, некоторые, как я узнал, например в IBA, вообще cvs пользуются. Подробно рассказывать именно про DVCS не думаю, что есть смысл, материалов на всех языках мира хватает, как в общем про DVCS, так и про конкретные системы. Один из главных зачинатилей всего безобразия, это Линус, так что в качестве введения можно посмотреть его выступление в кампусе Google, где в его духе эмоционально рассказано кто не прав и почему :)

Я расскажу про немного другую проблему. Когда вы делаете не свой продукт, а под заказ или являетесь всего лишь небольшим подпроектом огромного проекта, часть технологий вы выбрать не можете и вынужденны использовать subversion. Но ведь хочется вкусненького, и это возможно. Почти все разработчики DVCS понимают, что все сейчас прям не бросятся переводить свои репозитории на новые рельсы. Поэтому присутствует интеграция с многими другими системами контроля версий. Например с subversion. Вот хотел бы рассказать про hgsubversion, проект, который позволяет интегрировать subversion и mercurial репозитории. Был опробован на реальном проекте и пока никаких проблем не возникло.

Я, как думаю многие, на работе использую небезызвестную ОС от "Корпорации" :) Я конечно же привык к такому отличному приложению TortoiseSVN, клиент для работы с subversion репозиторием. Так что, для Mercurial я сразу выбрал программу с очень похожим названием TortoiseHg  :)Интерфейс практически аналогичный, с учётом разницы в самих типах репозиториев.

Теперь необходимо установить hgsubversion плагин к ней.

Для этого склонируем рипозиторий проекта с помощью уже установленной черепашики.

Я клонировал в подпапку установленного TortoiseHg. Теперь в домашнем каталоге пользователя найдите файл mercurial.ini и пропишите туда

[extensions]
hgsubversion = D:\Program Files\TortoiseHg\extensions\hgsubversion (понятно, что тут путь к установленному плагину :))

Если открыть TortoiseHg->Global Settings->Extentions, то можно увидеть, что всё установилось нормально.

Итак. Теперь интересный вопрос, как этот плагин будет работать с svn. Лично меня это порадовало. Как-то раньше пытался, что-то аналогичное с Git'ом провернуть и всё обламалось на том, что он не смог работать с репозиторием через https, сертификат чем-то ему не угодил. hgsubversion использовал установленный в системе subversion клиент и даже запомненный username/password, для него подтянул и не пришлось вводить, что лично меня вполне устроило. Раз понадобилась такая интеграция, то не от хорошей жизни, а потому что уже вдоволь наработались с subversion :)

Итак, теперь мы можем склонировать subversion репозиторий использую какой-то такой линк:
svn+https://localhost/svn/test

Может ругнуться в стиле:

Failed to open Subversion repository; please try running 'svn ls https://localhost/svn/test'

И, что необычно для open source проектов, это действительно полезный комментарий. Если запустить эту команду, то можно получить следующий диалог

>svn ls https://localhost/svn/test
Error validating server certificate for 'https://localhost:443':
 - The certificate is not issued by a trusted authority. Use the
   fingerprint to validate the certificate manually!
 - The certificate hostname does not match.
Certificate information:
 - Hostname: localhost
 - Valid: from Sat, 30 Oct 2010 08:37:10 GMT until Tue, 27 Oct 2020 08:37:10 GMT
 - Issuer: localhost
 - Fingerprint: 5d:22:af:1d:7a:9c:4e:05:d2:e6:49:d9:fa:3c:e9:df:ee:2a:b3:3c
(R)eject, accept (t)emporarily or accept (p)ermanently? p
Authentication realm: Subversion Repositories
Password for 'Pavel': ***********
Authentication realm: Subversion Repositories
Username: pavel_drobushevich
Password for 'pavel_drobushevich': *********
Test/

После чего clone отработает нормально.

Теперь у нас есть mercurial репозиторий, который связан с удалённый subversion репозиторием. Можно выбрать в меню Hg Repository explorer

И теперь с ним можно работать, как с обычным mercurial репозиторием, т.е. чтобы получить update'ы, использует pull комманду, а для того чтобы ваши коммиты попали в этот централизованный subversion репозиторий, использует соответственно push.

Что важно. Клонирование забирает в локальный mercurial репозиторий все коммиты, так, например, для нашего небольшого полугодовалого проекта, это заняло где-то полчаса, при не быстром соединении. Зато теперь у меня локально есть история изменений проекта за всё время его существования локально! И что самое забавное, засчёт различия в системе хранения, mercurial репозиторий со всей историей проекта, занимает всего лишь процентов на 5% больше места, в сравнений с svn checkout, который позволяет иметь только текущую ревизию :)

Ну и напоследок, чтобы все обзавидовались. Многие наверно знают, про команду Blane для svn, которая позволяет найти для конкретного файла commit, с текстом, к примеру кто и когда добавил новый field в класс. Так вот, с локальным mercurial репозиторием, я могу найти изменение во всём репозитории за всё время его существование, и очень быстро!

Ах, да, ещё в TortoiseHg включен небольшенкий, но крайне приятный webserver. Включив его, для вашего локального mercurial репозитория, вы сразу получаете обещанную децентрализацию, теперь коллеги могут работать как с центральным subversion репозиторием, так и с вашим mercurial!

В качестве итога. Если до сих пор в использовании DVCS вас останавливало обязательное наличие централизованного subversion репозитория, то сейчас как мне кажется, эта проблема уже не актуальна. Благодаря hgsubversion вы сможете работать с центральным subversion репозиторием как с обычным Mercurial репозиторием, получая колосальный profit от DVCS.

Решил добавить сюда пару советов.

1. Push в subversion. Такая проблема возникла не только у меня и решение не так очевидно, если не иметь большого опыта с HG. Ситуация следующая, было сделано несколько коммитов в локальный репозиторий и теперь мы хотим их push'нуть в центральный subversion репозиторий. Но со времени последнего pull'а туда тоже успели вкомитать. Поэтому черепашка попросит нас pull'нуть эти изменения к себе. В результате мы получаем вот такое разветвление:

Жёлтые это наши коммиты, со звёздочками это новые из subversion репозитория. Коммитать в таком виде нельзя. Надо или их объединять или выделять свои коммиты в отдельный branch. Я решил объеденить и эта была большая ошибка. К сожалению в таком виде нельзя push'ать в subversion. Потому что коммиты в subversion должны идти последовательно и такой merge анонимной ветки (в терминах Hg) невозможен. Поэтому правильное решение это сделать rebase  (необходимо подключить одноименный плагин). Тогда наши локальные комиты просто перемещаются в дереве выше новых коммитов и можно делать push.

2. Можно было заметить, что в 1 пункте я немного не правильно сделал, merge привёл к дополнительному коммиту в локальном репозитории, который мешал сделать rebase. Тут нам на выручку приходит ещё один замечательный Hg плагин MQ (это очень полезный плагин, но к сожалению не в том случае, когда приходится работать с центральным hgsubversion репозиторием). Он позволяет удалить коммит из локального репозитория.

3. И раз уж заговорил про бранчи. То, думаю, будет полезной статья A guide to branching in mercurial. По привычке с subversion я считал, что для ветвления нужно использовать именованные бранчи, но Hg предоставляет гораздо больше способов. С учётом, что я пользуюсь hgsubversion я выбрал самый первый, через clone. Очень удобно и точно ничего не испортишь.

4. И совсем маленькая подсказка. В черепашке в Hg Repository Explorer можно выбрать View -> Chose Details и в диалоге поставить галочку Subversion, тогда рядом с hg ревизиями можно будет видеть и соответствующие им subversion ревизии.

2 комментария:

  1. День добрый! При каждом заходе на репозиторий у клиента запрашивается пароль.Вы случайно не знаете как сделать так чтобы он не спрашивался на уровне авторизации в домене или можно ли это сделать с помощью клиентских сертификатов ssh или ssl?

    ОтветитьУдалить
  2. На уровне сервера к сожалению не знаю, так как с subversion серверами не сталкивался. Но я например конекчусь один раз к subversion серверу с помощью tortoisesvn и выбираю там галочку запомнить пороль (:

    ОтветитьУдалить