Распределённый контроль версий с Mercurial |
- Statistics
- Participants
- Translate into Russian
- Translation result
- 67% translated in draft. Almost done, let's finish it!
Copyright © 2006, 2007 Bryan O’Sullivan.
Материал может распространяться только при условии соблюдения положений и условий, изложенных в версии 1.0 лицензии Open Publication License. Текст лицензии можно посмотреть в Приложении D.
Английский оригинал книги собран из ревизии 028543f67bea (2008-08-20 15:27 -0700), с использованием Mercurial собранного из ревизии a58a611c320f.
Введение
Распределённые системы контроля версий — относительно новое явление, развивающееся благодаря стремлению
людей ко всему новому и непознанному.
Я пишу книгу о распределённых системах контроля версий (Version Control System — VCS или Revision Control System — RCS), так как считаю эту тему важной и заслуживающей хорошего руководства. Я решил написать о Mercurial потому, что это программное средство прекрасно подходит для учебных целей, и в то же время она справляется с задачами, которые не по силам многим другим системам контроля версий.
0.1 Работа над книгой ещё не закончена
Я публикую незаконченную книгу, потому что надеюсь, она будет полезной для всех интересующихся этой темой. И ещё я надеюсь, читатели помогут мне в написании книги так, как сочтут нужным.
0.2 О примерах в этой книге
В этой книге довольно необычные примеры. Каждый пример «живой» — фактически, это результат исполнения скрипта, который выполняет приведённые команды Mercurial. Каждый раз, когда книга собирается из исходников, все примеры автоматически исполняются и их текущие результаты сравниваются с ожидаемыми.
Плюс такого подхода в том, что примеры всегда верны; они описывают поведение в точности той версии Mercurial, которая указана в начале книги. Если я обновлю версию Mercurial, которую я описываю, и вывод какой-нибудь команды изменится — сборка книги не выполнится.
У этого подхода есть маленький недостаток, заключающийся в том, что даты и время, которые вы видите в примерах, слишком близки друг к другу, чего бы не происходило, если бы те же самые команды вбивал человек. Там, где человек может набрать не больше одной команды за несколько секунд, с соответствующим образом разнесёнными «отпечатками времени» (timestamps), мои автоматизированные примеры исполняют много команд за одну секунду.
Как пример этого, несколько последовательных коммитов в примере могут выглядеть исполненными в одну и ту же секунду. Вы можете увидеть это в примере использования команды bisect (деление пополам) в разделе 9.5.
Так что когда вы читаете примеры, не придавайте слишком большого значения датам или времени, которые вы увидите в результатах исполнения команд. Однако, будьте уверены, что поведение команд, которое вы видите, в целом верно и воспроизводимо.
0.3 Выходные данные — эта книга Свободна
Эта книга выпущена под лицензией Open Publication License, и создана исключительно с использованием Свободного ПО. Набрана она в LATEX; иллюстрации нарисованы и сформированы с помощью Inkscape.
Полный исходный код для этой книги выпущен в виде Mercurial хранилища и доступен по адресу http://hg.serpentine.com/mercurial/book.
Глава 1
Введение
1.1 О контроле версий
Контроль версий — это процесс управления множеством версий некой информации. В своём простейшем виде это то, что многие люди делают вручную: каждый раз, изменив файл, вы сохраняете его с новым именем, содержащим число, большее, чем число предыдущей версии.
Управление множеством версий кода даже одного файла — это задача, чреватая ошибками, так что программные инструменты для автоматизации этого процесса были сделаны довольно давно. Самые первые системы контроля версий предназначались для помощи пользователю-одиночке в управлении ревизиями одиночных файлов. На протяжении последних десятилетий область применения инструментов управления версиями очень сильно расширилась. Сейчас они управляют множеством файлов и помогают многим людям работать вместе. Лучшие из современных средств управления версиями без проблем справляются с тысячами людей, работающими совместно над проектами из сотен тысяч файлов.
1.1.1 Зачем нужен контроль версий?
Есть несколько причин, почему вы или ваша команда можете захотеть использовать автоматизированную систему управления версиями для проекта.
* Она будет отслеживать историю и прогресс вашего проекта вместо вас. Для каждого изменения у вас будет запись о том, кто его сделал, почему он это сделал, когда он это сделал и в чем заключалось изменение.
* Когда вы работаете с другими людьми, система контроля версий облегчает вам взаимодействие. Например, когда несколько человек делают потенциально конфликтные изменения одновременно, программа поможет вам определить и разрешить такие конфликты.
* Она может помочь вам восстановиться после ошибок. Если вы сделаете изменение, которое потом окажется ошибкой, вы сможете вернуться к более ранней версии одного или нескольких файлов. На самом деле, действительно хорошая система контроля версий даже поможет вам легко найти тот момент времени, когда проблема впервые появилась (см. раздел 9.5).
* Она поможет вам работать одновременно над несколькими версиями проекта и переключаться между ними.
Все эти причины одинаково важны (по крайней мере, в теории) независимо от того, работаете ли вы над проектом в одиночку или вместе с сотней других людей.
Ключевой вопрос относительно практичности системы контроля версий в таких разных средах («хакер-одиночка» и «огромная команда») в том, как преимущества соотносятся с «ценой» использования. Система, которую сложно понять или использовать, обойдётся дорого.
Проект для пятисот человек скорее всего развалится под собственным весом практически сразу, если в нём не используется система контроля версий и нет процесса разработки. В подобном случае даже говорить о цене использования контроля версий малоосмысленно, так как без неё провал практически неизбежен.
С другой стороны, проект «на коленке» для программиста-одиночки может показаться неудачным местом для использования системы контроля версий, потому как цена её использования наверняка будет сравнима с общей стоимостью всего проекта. Верно?
Mercurial уникален тем, что поддерживает оба предела размеров проекта. Вы можете изучить основы всего за несколько минут и, благодаря минимальным накладным расходам, вы с лёгкостию сможете применять управление версиями к наималейшим из проектов. Его простота означает, что вам не придется удерживать в голове множество маловразумительных концепций или последовательностей команд для того, чтобы совершить желаемое. В то же время, высокая производительность Mercurial и его распределённая природа позволит вам безболезненно увеличивать масштаб для управления большими проектами.
Никакая система контроля версий не поможет спасти скверно управляемый проект, но хорошие инструменты могут оказать значительное влияние на удобство работы над проектом.
1.1.2 Множество названий контроля версий
Контроль версий — довольно многозначное понятие, из-за чего для его обозначения существует множество разных названий и акронимов. Вот некоторые из них:
* Контроль ревизий (RCS, Revision control system)
* Конфигурационное управление (SCM, Software configuration management)
* Управление исходным кодом (Source code management)
* Контроль исходного кода (Source code control)
* Контроль версий (VCS, Version control system)
Некоторые люди утверждают, что на самом деле у этих терминов разные значения, но на практике они настолько сильно пересекаются, что нет общепринятого или хотя бы полезного способа вполне разделить их.
1.2 Краткая история контроля версий
Самая известная из старых утилит контроля версий — SCCS (Source Code Control System, система контроля исходного кода), которую написал Марк Рочкайнд (Marc Rochkind) из Bell Labs, в начале 70-х. SCCS оперировала отдельными файлами и требовала, чтобы каждый человек, работающий над проектом, имел доступ к общему рабочему пространству, существовавшему в единственном экземпляре. Только один человек мог одновременно редактировать файл в один момент времени; конфликты доступа к файлам разрешались блокировками. Обычной ситуацией было забывание снятия блокировки после редактирования, что запрещало доступ к файлу другим людям без помощи администратора.
Вальтер Тичи (Walter Tichy) разработал свободную альтернативу SCCS в начале 1980-х; он назвал свою программу RCS (Revision Control System, система контроля ревизий). Подобно SCCS, RCS требовала от разработчиков как работы в едином разделяемом рабочем пространстве, так и блокировки файлов для предотвращения одновременного изменения файлов разными людьми.
Позднее, в 1980-х же годах, Дик Грюн (Dick Grune) использовал RCS как основу для набора shell-скриптов, изначально названных cmt, а позднее переименованных в CVS (Concurrent Versions System, система одновременных версий). Крупное нововведение CVS заключалось в том, что она позволяла разработчикам работать одновременно и, в некоторой степени, независимо в их личных рабочих пространствах. Этими-то пространствами и предотвратилось беспрестанное наступание разработчиков друг другу на пятки, которое было обычным делом в SCCS и RCS. Каждый разработчик имел копию каждого файла проекта, разработчики могли модифицировать свои копии независимо. Им приходилось объединять собственные правки перед отсылкою изменений в центральное хранилище.
Брайан Берлинер (Brian Berliner) взял первоначальные скрипты Грюна и переписал их на Си, выпустив в 1989 году код, который впоследствии развился в современную версию CVS. CVS в дальнейшем приобрела возможность работать по сети, обретя клиент-серверную архитектуру. Архитектура CVS является централизованной: только на сервере есть копия истории проекта. Клиентские рабочие копии содержали только экземпляры файлов последней версии и небольшие метаданные для определения местонахождения сервера. Система CVS достигла невероятного успеха: вероятно, она является самой широко используемой системой контроля версий в мире.
В начале 1990-х годов Sun Microsystems разработала раннюю распределённую систему контроля версий, называвшуюся TeamWare. Каждая рабочая копия TeamWare содержала полную копию истории изменений проекта. Понятие центрального репозитория в TeamWare отсутствовало как таковое. (Подобно CVS, использовавшей RCS для хранения истории, TeamWare использовала SCCS.)
Шли 1990-ые, росла осведомлённость о нескольких проблемах CVS. Система записывает одновременные изменения нескольких файлов раздельно, а не группирует их в одну логически атомарную операцию. Способ управления файловой иерархией не очень хорош: нетрудно устроить в репозитории беспорядок, переименовывая файлы и каталоги. Более того, исходные коды CVS непросто понимать и поддерживать, что сделало практически непреодолимым «болевой порог» исправления этих архитектурных проблем.
В 2001 году Джим Бланди (Jim Blandy) и Карл Фогель (Karl Fogel) — два разработчика, прежде работавшие над CVS — начали проект по её замене таким средством, которое имело бы архитектуру получше и код почище. Результат, Subversion, не отошёл от централизованной клиент-серверной модели CVS, но добавил атомарные коммиты нескольких файлов, лучшее управление пространствами имён и другие возможности, которые сделали Subversion более удобным средством работы, нежели CVS. Со времени выхода первой версии Subversion быстро обретал популярность.
Более или менее одновременно, Грейдон Хоар (Graydon Hoare) начал работать над амбициозной системой контроля версий, которую назвал Monotone. Эта система не только устраняет множество проблем внутреннего устройства CVS и имеет распределённую архитектуру, но и идёт далее нескольких прежних (и последующих) систем контроля версий в некоторых своих нововведениях. Monotone использует криптографические хеши в качестве идентификаторов и имеет неотъемлемое представление о «доверии» коду из различных источников.
Жизнь Mercurial началась в 2005 году. В то время как некоторые аспекты его архитектуры были созданы под влиянием Monotone, Mercurial сосредоточен на простоте использования, высокой производительности и масштабируемости до очень больших проектов.
1.3 Тенденции в контроле версий
За последние четыре десятилетия в разработке и в использовании систем контроля версий, в то время как люди осваивают возможности своих инструментов и сталкиваются с их ограничениями, безошибочно явствует некая тенденция.
Первое поколение начинало с управления одиночными файлами на индивидуальных компьютерах. Хотя эти инструменты имели большое преимущество над специализированным ручным управлением версиями, их блокирующая модель и зависимость от одного компьютера позволяли применять их лишь в тесных маленьких командах.
Второе поколение ослабило эти ограничения переходом на сетевые архитектуры и комплексное управление проектами. По мере роста проектов появлялись новые проблемы. Когда клиентам нужно было очень часто взаимодействовать с серверами, масштабирование сервера становилось сложной задачей на больших проектах. Ненадёжное соединение с сетью могло вообще не давать отдалённым пользователям общаться с сервером. Когда проекты с открытым кодом стали давать всем анонимный доступ только на чтение, люди, не имеющие достаточных прав для внесения изменений, обнаружили, что не могут использовать инструменты для взаимодействия с проектом естественным образом, так как не могут записать свои правки.
Современное поколение инструментов контроля версий — по природе децентрализованное (peer-to-peer). Все эти системы устранили зависимость от одного центрального сервера и позволили людям передавать их данные контроля версий туда, где действительно есть в них нужда. Сотрудничество через Интернет, прежде ограниченное технологией, ныне стало вопросом выбора и согласия. Современные инструменты могут действовать и без сети, неограниченно и автономно, испытывая нужду в сетевом соединении только при синхронизации изменений с другим репозиторием.
1.4 Некоторые преимущества распределённого контроля версий
Хотя инструменты распределённого контроля версий уже несколько лет так же надёжны и удобны, как и их аналоги предыдущего поколения, люди, использующие старые инструменты, ещё не осознали преимущества новых. Во многих отношениях распределённые инструменты блистают по сравнению с централизованными.
Для отдельного разработчика распределённые инструменты практически всегда намного быстрее централизованных. Этому есть простое объяснение: централизованная утилита для многих обыденных операций должна общаться по сети, поскольку большинство метаданных хранятся в единственном экземпляре на центральном сервере. Распределённый инструмент хранит все свои метаданные локально. При прочих равных условиях общение по сети увеличивает накладные расходы использования централизованного инструмента. Не недооценивайте значимость шустрого, быстро реагирующего инструмента: вам доведётся провести массу времени, взаимодействуя с системою контроля версий.
Распределённые инструменты безразличны к причудам вашей серверной инфраструктуры, опять же потому, что они создают дубликаты метаданных во множестве мест. Если вы используете централизованную систему, а ваш сервер воспламенится, то останется надеяться на то, что резервные копии надёжны, и что последнее создание их прошло успешно и не очень давно. С распределённым инструментом вам доступно множество резервных копий — на компьютере у каждого разработчика.
Надёжность вашего сетевого соединения будет влиять на распределённые системы значительно меньше, чем на централизованные. А использовать централизованную утилиту без сетевого соединения у вас даже не получится, за исключением нескольких сильно ограниченных команд. С распределённой системой отключение сетевого соединения во время работы вообще может пройти незамеченным. Единственное, что будет невозможным — запросы к репозиториям на других компьютерах, что происходит не так уж и часто по сравнению с другими операциями. Если вы состоите в группе разработчиков, находящихся на большом расстоянии друг от друга, это может быть важным.
1.4.1 Преимущества для проектов с открытым исходным кодом
Если вы нашли открытый проект, над которым вам хотелось бы поработать, и проект использует распределённую систему контроля версий, вы находитесь на одной ступеньке с людьми, которые являются "ядром" проекта. Если они публикуют свои репозитории, вы можете незамедлительно копировать историю разработки, делать изменения и записывать их точно так же, как это делают полноправные участники проекта. Централизованную систему, напротив, придётся использовать в режиме «только чтение», если только кто-нибудь не даст вам достаточно прав для фиксирования изменений на центральном сервере. До тех пор у вас не будет никакой возможности фиксировать изменения и они будут под риском искажения каждый раз при обновлении рабочей копии репозитория.
Ветвления - не проблема
Есть мнение, что распределённые системы контроля версий добавляют риска проектам с открытым исходным кодом, поскольку делают простым ветвление разработки проекта. Это случается, когда существуют разногласия во взглядах или отношениях между группами разработчиков, которые ведут к принятию ими решения о невозможности работать вместе. Тогда каждая сторона берёт более или менее полную копию исходного кода проекта и идёт в своём собственном направлении.
Иногда стороны решают объединиться и согласовать изменения. С централизованной системой процесс слияния изменений технически очень сложен и в основном должен быть произведён вручную. Вам придётся решать, чья история "выиграет", и каким-то образом прививать изменения другой команды. Обычно при этом теряется история изменений одной или обеих сторон.
Распределённые системы поступают с ветвлением очень просто — они объявляют его единственным путём развития проекта. Каждое изменение, которое вы делаете, потенциально является точкой ответвления. Силой такого подхода является то, что инструмент должен быть действительно хорош в объединении веток, потому что ветки крайне важны: они всё время создаются.
Если каждый кусочек работы, делаемой всеми, всегда оформляется в терминах ответвления и слияния, тогда то, что мир открытого ПО называет "ветвлением", становится исключительно социальной проблемой. Как бы то ни было, распределённые системы понижают вероятность ветвления:
* Они убирают социальное разделение, которое привнесли централизованные системы — между инсайдерами (теми, кто может вносить изменения) и аутсайдерами (теми, кто не может).
* Они упрощают воссоединение после социального ветвления, так как с точки зрения контроля версий это ничем не отличается от обычного слияния.
Некоторые люди сопротивляются использованию распределённого контроля версий, потому что хотят сохранить за собой строгий контроль над своими проектами, и думают, что централизованные системы дадут им его. Тем не менее, если вы придерживаетесь таких убеждений, и при этом разрешаете публичный доступ к своему CVS/Subversion репозиторию, то знайте, что существует множество инструментов, позволяющих вытащить полную историю вашего проекта (пусть даже и медленно) и пересоздать её в таком месте, которое вы не сможете контролировать. Таким образом получается, что ваш контроль в этом случае иллюзорен, и в то же время вы потеряли возможность гибко сотрудничать с теми людьми, которые почувствовали себя вынужденными продублировать вашу историю или ответвиться от неё.
1.4.2 Преимущества для коммерческих проектов
Команды многих коммерческих проектов зачастую разбросаны по всему земному шару. Территориально удалённые от главного сервера разработчики могут сталкиваться с такими проблемами, как замедленная реакция на выполнение команд и, возможно, перерывы в доступности системы. Коммерческие системы контроля версий предлагают решение данной проблемы в виде расширений для удалённой репликации данных. Такие расширения как правило довольно дороги и сложны для администрирования. Распределённые системы изначально лишены подобных недостатков. Более того, можно установить несколько проектных серверов, скажем один в каждом офисе, для сокращения объёма избыточного трафика между репозиториями через дорогие каналы связи.
Централизованные системы контроля версий как правило обладают ограниченной масштабируемостью. Падение дорогой централизованной системы под нагрузкой, вызванной одновременным обращением всего пары дюжин пользователей, не является чем-то необычным. Повторяясь, наиболее типичным решением проблемы будет дорогой и тяжелый механизм репликации. Так как нагрузка на главный сервер — даже если он единственный — для распределённого инструмента контроля версий во много раз меньше (потому что все данные реплицируются повсюду), один недорогой сервер может удовлетворять потребности гораздо более многочисленной команды разработчиков и для репликации с целью распределения нагрузки нужно лишь написать несложные скрипты.
Если некоторые члены вашей команды работают "в поле", разрешая проблемы на площадке заказчика, они также получают определённые преимущества от использования распределённой системы контроля версий. Инструмент позволит им строить кастомные сборки, пробовать различные исправления изолированно друг от друга, а также проводить эффективный поиск причины ошибки в среде заказчика с использованием истории версий. Всё это может быть выполнено без необходимости в постоянном соединении с внутренней сетью компании.
1.5 Почему следует остановить выбор на Mercurial?
Mercurial обладает уникальным набором свойств, позволяющим выбрать его в качестве наиболее подходящей системы контроля версий.
* Прост в изучении и в использовании
* Легковесный
* Превосходно масштабируется
* Легко настраивается под конкретные нужды
Если вы обладаете опытом в использовании систем контроля версий, вам потребуется меньше пяти минут, чтобы начать работать с Mercurial. Если же вы новичок, процесс знакомства не должен занять больше десяти минут. Mercurial предоставляет единообразную и последовательную систему команд и функций, что позволяет руководствоваться небольшим набором общих правил вместо того, чтобы учить массу исключений.
В небольших проектах вы можете начать работу с Mercurial в считанные минуты. Создание новых веток и изменений, распространение изменений (как локально, так и по сети), операции с историей и статусом — всё это работает быстро. Mercurial старается быть незаметным и не путаться под вашими ногами, не требует от вас больших умственных усилий и совершает свои операции невероятно быстро.
Mercurial применяется не только в маленьких проектах, его используют и в проектах с сотнями и тысячами разработчиков, проектах, которые содержат десятки тысяч файлов и сотни мегабайт исходного кода.
Если вам не хватает базовой функциональности Mercurial, то её легко расширить. Mercurial хорошо подходит для задач скриптинга, его понятное устройство и реализация на языке Python позволяет легко добавлять новые возможности в виде расширений. Существует большое количество популярных и полезных расширений, охватывающих спектр задач от помощи в нахождении ошибок до улучшения производительности.
1.6 Mercurial в сравнении с другими системами контроля версий
Прежде чем вы продолжите чтение, вам следует уяснить, что этот раздел отражает мой опыт, интересы и (да, я осмелюсь сказать это) мои наклонности. Я использовал каждую из перечисленных ниже систем контроля версий в большинстве случаев в течение нескольких лет.
1.6.1 Subversion
Subversion — популярная система контроля версий, разработанная с целью заменить CVS. Subversion имеет централизованную клиент/серверную архитектуру.
Subversion и Mercurial имеют похожие команды для одних и тех же операций, так что если вы хорошо знаете одну из этих систем, вам легко будет научиться пользоваться другой. Обе системы портированы на все популярные операционные системы.
У Subversion отсутствует возможность слияния с учетом истории изменений, что заставляет пользователей вручную отслеживать какие из ревизий были слиты между ветками. Если пользователи этого не делают или допускают ошибки, они сталкиваются с необходимостью ручного разрешения необязательных конфликтов при слиянии. Subversion также не может слить изменения если файл или каталог был переименован. Плохая поддержка слияния - единственный крупный недостаток Subversion.
Mercurial обладает большей производительностью, чем Subversion, в каждой операции, производительность которой я измерял. Скорость больше в 2-6 раз, когда речь идет о локальном репозитории Subversion 1.4.3 (самый быстрый метод доступа). При более реалистичном варианте использования - сетевой репозиторий, Subversion находится в существенно худшем положении. В силу того, что команды Subversion должны взаимодействовать с сервером и при этом Subversion не имеет полезных средств репликации, производительность сервера и пропускная способность сети становятся узкими местами даже для некрупных проектов.
Кроме того, Subversion требует дополнительное дисковое пространство для того, чтобы избежать сетевых запросов при выполнении некоторых операций: поиск модифицированных файлов (status) и отображение изменений (diff). В результате рабочая копия Subversion такого же размера (а то и больше) как репозиторий Mercurial и рабочий каталог вместе взятые, хотя репозиторий Mercurial содержит полную историю проекта.
Subversion имеет широкую поддержку инструментария сторонних производителей. В этом отношении у Mercurial сейчас существенное отставание. Хотя разрыв сокращается, и некоторые GUI-утилиты для Mercurial превосходят свои аналоги для Subversion. Как и Mercurial, Subversion располагает отличным руководством пользователя.
Из-за того, что Subversion не хранит историю изменений на клиенте, она хорошо подходит для управления проектами, содержащими большое количество двоичных файлов. Если вы внесете в несжимаемый десятимегабайтный файл 50 изменений, то дисковое пространство, использованное Subversion останется неизменным. Пространство, используемое любой из распределенных систем контроля версий, будет быстро увеличиваться пропорционально количеству изменений, потому что различия между правками большие.
Кроме того, обычно трудно, а чаще невозможно слить разные версии двоичного файла. Subversion позволяет пользователю заблокировать файл, в результате пользователь на время получает эксклюзивные права на внесение изменений в него. Это может быть значительным преимуществом для проекта, в котором широко используются двоичные файлы.
Mercurial может импортировать историю изменений из репозитория Subversion. Возможен и обратный процесс. Это делает возможным прощупать почву и использовать Mercurial и Subversion одновременно, прежде чем решить, осуществлять переход или нет. Преобразование истории — пошаговый процесс, так что вы можете осуществить начальное преобразование, а потом вносить новые изменения.
1.6.2 Git
Git — распределенная система контроля версий, которая была разработана для управления исходниками ядра Linux. Как и у Mercurial, на начальный дизайн системы оказал влияние Monotone.
Original (English): Distributed revision control with Mercurial
Translation: © Dmitry, Игорь, ChivPointDJ, f73, hhg, vbor, Адель Чепкунов, wise, ktbjn, Александр, ak, Александр Соловьёв, dustin86, Евгений, hntr.spb.ru, scr, Zveroy, DeKar, certain, aafin, maxischenko, Mammoth, kolen, linuxena, Mithgol, tven, Andy, salnikov-a, MaksBR, Валерий, miramir, iav, flower-child, Денис, Demiodv Viktor, Владимир, zakhar, anatoly.rakovskiy, smilesrg, marie-lo, traditio, PhoeniXDN, vkhamianok, Sign, Passerby, wikiwikiweb, vour, dolinenko, minimus, ivan.borzenkov, kedo-kyn, Hikin, pioneer-hg, RANUX, Антон Ильин, russiankamikaze, dalek, levin-matveev, altanzar, poige, KorRomMar, vperlin, lakearo, Anton Abrosimov, boz, Александр Копилов, supdev, xalava, molnij, exvion, and_rew, Dieu_Mort, Андрей Дягель, Mirray, denger, murkt.org.ua, relanium-ilya, eugenius-nsk.livejournal.com, ladykosha, wert_lex, hyperon, laway .
License: Open Publication License version 1.0
