Изменения

Перейти к: навигация, поиск

Сравнение DVCS - несколько задач

6141 байт добавлено, 15:47, 2 августа 2010
м
Нет описания правки
Данная статья является очередным сравнением популярных [[wikipedia:Distributed revision control|DVCS]] — [http://selenic.com/mercurial/ Mercurial], [http://git-scm.com/ Git] и [http://bazaar-vcs.org/ Bazaar], с точки зрения нескольких нетривиальных задач. Ссылка: [http://yourcmc.ru/DVCS_YAC http://yourcmc.ru/DVCS_YAC] («Yet Another Comparison»). Хотите лаконичный ответ в стиле «ИМХО» на вопрос — кого выбрать из трёх? Ну пожалуйста. Выбирайте Mercurial. А не Git (безумный конгломерат) и не Bazaar (пионерское поделие, унаследованное от Arch’а).
== Работа с SVN (миграция и синхронизация) ==
=== Mercurial ===
'''Mercurial''': было бы почти отлично(5-), но есть баги… Есть несколько расширений — 3 расширения различной степени глюкавости — [http://mercurial.selenic.com/wiki/HgSubversion hgsubversion], [http://pypi.python.org/pypi/hgsvn hgsvn], [http://mercurial.selenic.com/wiki/ConvertExtension convert], из которых позволяющих работать с Subversion тем или иным образом, и не совместимых друг с другом.  Самое вменяемое из них — этих расширений — '''hgsubversion''', но и хотя оно ещё сыровато, иразработка ведётся активно, к сожалениюв мэйллисте постоянно происходит некая жизнь, не распространяется вместе а автор отзывчив. Вместе с Mercurial’омоно не распространяется, нужно ставить отдельно. Тестировалась ревизия Тестировал я ревизию 500 из http://bitbucket.org/durin42/hgsubversion.
Имеет основной необходимый функционал — можно делать и <tt>push</tt>, и <tt>pull</tt> в/из Subversion, можно клонировать SVN-репозиторий с сохранением веток и меток (правда, обязательно стандартное их расположение в корневых поддиректориях <tt>/trunk</tt>, <tt>/branches</tt>, <tt>/tags</tt>), эти два метода совместимы, <tt>rebase</tt> работает, граф ветвлений сохраняется. Очень крут тот факт, что ветка, которая создавалась неполным копированием <tt>trunk</tt>'а, то есть, копированием некоторых его поддиректорий, успешно подцепилась в нужное место графа ветвлений. Ни Bazaar, ни Git этого не смогли. Поддержки svn:mergeinfo пока что нет, хотя она близится.
Минус расширения заключается в сырости — за время тестирования я нашёл уже несколько неприятных багов:
* <tt>push</tt> из Mercurial-клона репозитория без веток и меток (имеющего вид просто одного каталога) в Subversion не работал вообще — [http://groups.google.com/group/hgsubversion/browse_thread/thread/3749eb3cbf007855 обсуждение в группе hgsubversion]. К счастью, меня пропёрло, я потратил час времени и баг этот пофиксил собственноручно. [[hgsubversion-fix-for-singledir-repo.diff|Фикс]] очень простой, на две строчки, и он уже находится в репозитории в виде ревизии r501 — за отзывчивость автору зачёт.
* <s>Не работает клонирование репозиториев по протоколу [http://svnbook.red-bean.com/en/1.0/ch06s03.html svnserve] (<tt>svn://host:port/url</tt>). Очень неприятно, особенно, если вы предпочитаете именно <tt>svnserve</tt> по причине его производительности.</s> Уже давно работает.
* Течёт память, что при клонировании '''толстых''' SVN-репозиториев (например, [http://svn.wikimedia.org/svnroot/mediawiki/ репозитория MediaWiki]) приводит к ошибкам <tt>Abort: out of memory</tt>, то есть нехватки памяти. Обходится методом клонирования репозитория по частям, делая <tt>hg init</tt>, а потом несколько <tt>hg pull</tt> до победного конца. Причина в дырявости [http://www.swig.org/ SWIG] SVN Python-библиотеки. Забавно, что аналогичная [http://www.swig.org/ SWIG] Perl-библиотека такой текучестью, видимо, не страдает, так как Git этот репозиторий глотал (причём по 10 раз за раз) и не давился. ''Perl, говорите, течёт? Ну хи-хи, хи-хи.'' Кстати, Bazaar течёт точно так же, как <tt>hgsubversion</tt>.
* На ревизии 43380 MediaWiki <tt>hgsubversion</tt> свалился с ошибкой <tt>abort: phase3/includes/ConfigurationCache.php@a1335975fba6: not found in manifest!</tt>. [http://groups.google.com/group/hgsubversion/browse_thread/thread/2a2ae0aa680054ec обсуждение в группе hgsubversion]. Причина, вероятно, кроется где-то в районе обработки перемещений каталогов Subversion. Я обошёл данный баг убиением части файла <tt>.hg/svn/rev_map</tt> (можно было и весь убить) и перезапуском <tt>hg pull</tt>. Однако в итоге появилось две ветки вместо одной: <tt>on_wiki-configuration</tt> и <tt>on_wiki-configuration/phase3</tt> (подкаталог ветки…)
Итог клонирования MediaWiki-репозитория: успешно с небольшими бубнами (танцами с бубном — склонировал за несколько перезапусков <tt>pull</tt>'а и с уборкой <tt>rev_map</tt> в середине), все ветки на месте, только одна, перемещённая потом в подкаталог себя, продублировалась: «<tt>on-wiki_configuration</tt>» и «<tt>on-wiki_configuration/phase3</tt>». Репозиторий (то есть директория <tt>.hg</tt>) занимает на диске '''1.63 Гб'''.
Остальные два экстенжна «нинужны»: <tt>hgsvn</tt> — нечто более старое, работает сбоку от общего механизма, тоже позволяет делать push и pull, но не клонирует весь репозиторий, а только извлекает (checkout’ит) последнюю версию, чтобы далее можно было использовать Subversion и Mercurial вместе. Ну и конечно, оно не совместимо с <tt>hgsubversion</tt>. <tt>convert</tt> же предназначен для конвертации истории проекта из нескольких различных систем контроля версий в Mercurial, ни черта не совместим ни с <tt>hgsvn</tt>, ни с <tt>hgsubversion</tt> и не сохраняет граф ветвлений. Зато, правда, поддерживает возможность использования других имён поддиректорий <tt>trunk/branches/tags</tt>.
<div style="height: 150px; overflow: scroll">{{:hg-rebase-better-than-bzr-ithelps.sh}}</div>
=== Итоги клонирования SVN MediaWiki ===
Место на диске:
# Git — * '''Git''' — 845 мб.# Bazaar — * '''Bazaar''' — 925 мб.# Mercurial — * '''Mercurial''' — 1633 мб.
«Нечестные» ветки (<tt>svn cp trunk/phase3 trunk/extensions branches/ветка/</tt>):
# Mercurial — * '''Mercurial''' — корректно прицепились к trunk’у(!).# Git — * '''Git''' — общая история у всех таких веток, но отдельная от trunk’а.# Bazaar — * '''Bazaar''' — история «ДО» создания нечестных веток потеряна.
Проблемы:
* Git — '''Git''' — клонирование SVN идёт очень долго, много данных копируется повторно.* Mercurial — '''Mercurial''' — течёт память, проблема с <tt>rev_map </tt> в середине клонирования.* Bazaar — '''Bazaar''' — течёт память, проблемы с <tt>rebase, по ощущению производительность поменьше</tt>.
== Управление патчами ==
Чего не хватает (а хочется):
* легко Легко создавать патчи, зависящие от нескольких других(хотя это можно делать и вручную).* легко Легко поддерживать ветку, содержащую объединение всех патчей — для развёртывания.* удалять Удалять зависимости патчей.
Хотя и Первые два пункта в pbranch делаются как-то, уж совсем нелогично — нужно '''ручками''' прописать зависимость патча в файл <tt>.hg/pgraph</tt> и другоевызвать команду <tt>hg pmerge</tt>, которая автоматически объединит все пока что не объединённые зависимости в принципенеобходимые ветки. Очень странно, сделать что предписано общаться через <tt>.hg/pgraph</tt> при том, что этот файл вообще-то не является никаким «окончательным хранилищем» — его скорее можно классифицировать, как кэш команды <tt>pgraph</tt> — если его удалить, он будет успешно воссоздан, и такпри клонировании репозитория он также не копируется. Плюс же расширения заключается  Зато, в отличие от TopGit, '''pbranch''''евый репозиторий без проблем клонируется со всеми ветками и информацией о патчах, и документация на '''pbranch''' [http://arrenbrecht.ch/mercurial/pbranch/index.htm хорошей online-документациивесьма вменяема] — у TopGit такой нет… ===== Пример использования ===== Лично я, для управления патчами MediaWiki, входящими в состав CustIS’овской сборки MediaWiki, и хранящимися под SVN в виде набора diff-файлов, выбрал именно '''pbranch''' и следующую схему работы:* SVN-репозиторий компании содержит директорию <tt>custisinstall</tt> с конфигурационными файлами и патчами в виде diff’ов и директорию extensions с расширениями, написанными либо сильно модифицированными (по сути «форкнутыми») нами. Без веток, без меток.* Ветка <tt>default</tt> содержит импортируемый <tt>hgsubversion</tt>'ом SVN-репозиторий.* Ветка <tt>mediawiki</tt> содержит дистрибутив оригинальной MediaWiki в том виде, в каком он должен присутствовать в DocumentRoot’е, плюс расширения, слабо модифицированные (патчами) или вообще не модифицированные нами, в поддиректории <tt>extensions</tt>.* На основе ветки <tt>mediawiki</tt> создаются отдельные ветки для независимых друг от друга патчей в код MediaWiki и/или код расширений из ветки mediawiki.* Для патчей, зависящих от других, создаются ветки на основе веток этих патчей.* Ветка <tt>all</tt> содержит объединение всех веток патчей.* Ветка <tt>mergeinstall</tt> содержит объединение веток <tt>all</tt> и <tt>default</tt> и используется для развёртывания.* Все зависимости между ветками автоматически отслеживаются '''pbranch''''ем. Таким образом, для установки нашей сборки MediaWiki через Mercurial надо только клонировать репозиторий и обновиться до ветки mergeinstall — сразу же будут получены все патчи и расширения. При этом все патчи с помощью команды <tt>hg pdiff</tt> экспортируются в diff-файлы и коммитятся в Subversion, поэтому доступен и старый метод установки — Python-скрипт, выкачивающий из svn.wikimedia.org код MediaWiki, из локального Subversion’а — код нужных расширений и патчи, и накатывающий эти патчи на MediaWiki автоматически.
==== TopGit ====
Чего не хватает (а хочется):
* удалять Возможности клонирования репозитория с учётом TopGit’а.*: С клонированием Git, как известно, выпендривается своими «[http://www.gitready.com/beginner/2009/03/09/remote-tracking-branches.html Remote Tracking Branches]», а TopGit, к сожалению, не полностью основан на стандартных механизмах Git. Поэтому с помощью команд <tt>git clone</tt> или <tt>git pull</tt> скопировать репозиторий с сохранением всей информации TopGit невозможно. Между прочим, весьма серьёзный недостаток.* Удалять зависимости патчей. *: То есть — реально есть по-настоящему удалять зависимости, а не просто отменять изменения. Но это в TODO перечислено и, вероятно, будет реализовано.
== Схема управления рабочими копиями ==
'''Mercurial''' говорит нам: на ровно 1 рабочую копию ровно 1 репозиторий, и иначе быть не может. Это и удобно — сказал <tt>hg up ветка_такая_то</tt>, пара файлов поменялась, и опа — ты уже в другой ветке. Это и неудобно — чтобы положить на диск одновременно две разных ветки, нужно обязательно клонировать репозиторий (поддержки checkout нет).
С '''Git''''ом ситуация почти такая же, как и с Mercurial’ом. 1 рабочая копия, 1 репозиторий. Хотя при клонировании данные репозитория можно и не копировать, задавая опцию <tt>--shared</tt>, но это скорее похоже на Bazaar’овские [http://doc.bazaar-vcs.org/latest/en/user-guide/stacked.html Stacked Branches], чем на Lightweight Checkout. Идея checkout’ов, или лёгких рабочих копий (или «идея .gitlink») [http://git.or.cz/gitwiki/SoC2007Ideas высказана для GSoC-2007], однако (пока ?) так и не реализована.
Управление ветками в '''Bazaar''' вначале было гораздо хуже: на 1 ветку ровно 1 рабочая копия и ровно 1 репозиторий. Однако потом появилось уникальное: <tt>checkout</tt>'ы и [http://bazaar-vcs.org/SharedRepositoryTutorial Shared Repository], имеющий опцию <tt>--no-trees</tt>. Таким образом, стало возможно иметь сколько угодно репозиториев и сколько угодно рабочих копий. В Git и Mercurial этого нет. Переключать легковесную рабочую копию с ветки на ветку Bazaar тоже умеет — командой <tt>switch</tt>, для переключения ветки её надо превратить в легковесную рабочую копию командой <tt>bind</tt>.
[[Категория:Разработка]]
[[Категория:Статьи]]

Навигация