Software Configuration Management // Распределенный контроль версий

    Приветствую. Как и обещал — продолжение цикла заметок об управлении конфигурацией ПО, в простонародье называемом Software Configuration Management. Весь цикл можно найти по ссылке на тэг CM. Из ещё неохваченного осталась буквально пара заметок.

    Сегодня речь пойдет о довольно спорном и в чём-то провокационном вопросе — распределенных системах контроля версий. Знаю, что подобные системы популярны среди хабравчан, так что заранее готов в обсуждению. Более того — призываю не проходить мимо и высказаться, если есть что сказать по делу.


    Итак, есть проект и в нём — система контроля версий, обслуживающая несколько команд, которые этот проект реализуют. Система контроля версий — одна на всех. Напомню, что я продолжаю серию заметок, и раньше я рассказывал о контроле версий вообще, обойдя конкретные реализации стороной. Так что предметная область тоже постепенно эволюционирует от простого к сложному.

    Так вот, в какой-то момент возникает необходимость сделать доступным центральное хранилище локально в одном из центров разработки – для ускорения работы и обхода ограничений по трафику или пропускной способности. Скажем, есть две команды, расположенные территориально в разных местах и часовых поясах – скажем, Дальний Восток России и Центральная временная зона США, их разделяет полмира. Работа идет над одним проектом, и есть необходимость менять одни и те же части продукта. Предположим, что сервер системы контроля версий стоит в США – соответственно, разработчикам в России для создания каждой новой версии приходится отправлять изменения через половину земного шара. Да и любая операция вроде перехода на другую ветку со взятием целиком всей выбранной конфигурации, будет отнимать слишком много времени, учитывая величину пинга. В общем, в подобных ситуациях централизованное хранилище – не самый удобный вариант.

    Поскольку проблема не нова и актуальна, со временем были сформулированы разные подходы к решению задачи. А точнее – два подхода к построению распределенных систем контроля.

    Открытое распределение – это принцип построения, при котором каждая рабочая копия конфигурации может иметь свой набор дочерних версий и обмен созданными версиями происходит по выбору создателя изменений.

    Плюсом подобных систем является то, что работа на отдельной рабочей станции может идти независимо от других экземпляров хранилища. Собственно, хранилища может и не быть – сколько копий, столько и хранилищ. Не удивительно, что подобные системы нашли применение в первую очередь в Open Source. Отсутствие необходимости содержать отдельный сервер дает возможность обмениваться только той информацией, которая нужна, и не перегружать хранилище и трафик той дельтой, которая может кому-то никогда так и не понадобиться.
    Минус подобного подхода в том, что обмен дельтой рабочих продуктов плохо поддается централизованному контролю. Получается некоторое броуновское движение дельты, которое многим менеджерам, привыкшим к централизации, может быть не по душе.
    Примерами подобных систем могут быть BitKeeper, git, Mercurial (Hg).

    Распределение путём репликации предусматривает создание равноценных копий центрального хранилища данных (или его частей) на всех распределенных серверах. Здесь можно провести аналогию с базами данных и их репликацией. Для каждого разработчика хранилище версий, к которому он подключается, является основным. Все версии и ветки создаются в центральном хранилище или реплике. Для распределения данных делается копия хранилища на другие имеющиеся сервера и часть разработчиков переключается на сделанную копию. При необходимости обмена результатами работы, происходит репликация хранилища – оба сервера обмениваются метаинформацией.

    Плюсом подобного подхода можно считать централизацию работы в рамках одного местоположения команды. Также стоит добавить, что имеется возможность удерживать часть накопленной информации от синхронизации с другими командами, но в то же время делать её доступной одновременно всей локальной команде. Это бывает важно, когда код разрабатываемых подсистем не должен попадать наружу – даже для других команд, работающих над этим же продуктом.

    Минус – необходимость настройки механизмов репликации. Но, как правило, системы, использующие такой подход, предусматривают инструменты эффективного обмена данными. Кроме того, для кого-то может быть минусом тот факт, что все операции с версиями производятся на одном сервере, а не на локальном компьютере разработчика. То есть «распределённость» системы проявляется на уровне команд и их местоположения, но никак не на уровне простого разработчика.
    Примерами систем с репликацией служат ClearCase и Perforce.

    Оба типа (открытый и репликационный) схожи между собой — в обоих случаях происходит обмен информацией между разными копиями одного множества элементов и их версий. Разница между ними – в «масштабах». В системах с репликацией минимальной единицей реплики, как правило, является репозиторий или его значимая часть, обрабатываемая как единое целое. В системах с открытым распределением минимальная единица обмена информацией – это отдельная версия отдельного элемента.
    Для обоих типов распределения характерна общая проблема. Это необходимость введения четкого соглашения об именовании элементов и их веток, а также меток для обозначения полученных конфигураций. При соединении результатов работы не должны получаться разные файлы с одним и тем же именем и метаинформацией (ветками, метками, атрибутами). Поэтому все разработчики и команды, работающие отдельно друг от друга, должны придерживаться общих стандартов. В разных системах бывают предусмотрены механизмы для обеспечения этого условия. К примеру, при работе с ClearCase создаются триггеры на создание любой метаинформации, проверяющие её на соответствие стандарту – для всех создаваемых веток ставится необходимым наличие в имени ветки кода (или идентификатора) того сайта (команды), в котором ветка была создана.

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

    Какой из подходов лучше, конечно, нельзя сказать сразу и для всех проектов. Приспосабливать для работы броуновское движение git'а или остановиться на более стабильном состоянии – решать менеджменту каждого проекта. Единого решения для всех команд и проектов нет и быть не может. Кому интересно посмотреть на различия разных систем и моделей – см. ссылку [1].

    Кстати, распределенными могут быть не только системы контроля версий, но и системы отслеживания запросов на изменение. Логика работы совершенно аналогична. Вот только основная модель работы – репликационная. Пример – IBM Rational ClearDDTS. Поскольку подобные системы не очень распространены, останавливаться на них подробно не будем.

    По традиции, использованные и рекомендуемые для самостоятельного изучения источники:
    1. en.wikipedia.org/wiki/Comparison_of_revision_control_software — сравнение систем контроля версий;
    2. lib.custis.ru/index.php/The_Risks_of_Distributed_Version_Control — трезвый взгляд на риски, связанные с распределенными системами контроля версий;

    Порекомендую ещё одну статью о проблемах внедрения разных систем контроля версий:
    lib.custis.ru/index.php/Version_Control_and_%E2%80%9Cthe_80%25%E2%80%9D
    Немного провокационная, однако стоит прочитать в первую очередь тем, кто относит себя к прогрессивной части программерского сообщества. И, заранее отвечая на вопрос: нет, я не фанат ни SVN, ни git.

    На сегодня всё. Не проходим мимо, высказываемся. Интересно услышать мнение людей, использовавших Perforce.
    Поклонники git/Hg/etc — интересно услышать о не очевидных проблемах, возникающих при обмене дельтой (они ведь должны быть, ничто не бывает гладко и идеально).
    Если кто делал репликацию репозиториев в SVN или даже CVS — расскажите, будет вам благодарность.

    Ну и — продолжение следует.

    Комментарии 45

      0
      Косячок-с про влияние пингов на скорость получения инфы… Поясняю: величина задержек будет общей для всего запроса, а не для каждого пакета в отдельности. Ну будет оно дольше на 100 мкс, ну и пусть. Ощутимее не станет.
        0
        Про пинг — это я образно. Тут скорее будет вообще скорость прокачки влиять — а она имеет свойство уменьшаться в зависимости от удаленности хоста.
          +1
          если объемы данных более >100мб и для мегабитной линии — да. Но такое сейчас не очень-то и часто — исходники весят гораздо меньше, картинки пересылаются 1 раз, да и интернет стремительно «скоростеет». Т.е. это просто не аргумент — так зачем его сбоку приплетать? Так ведь особо въедливые могут подумать, что и не про пинг — это тоже образное.
            0
            Приведу пример из жизни. Я уже поминал в постах, что работал в компании-контракторе Моторолы. Сидя во Владике, мы работали удаленно с серверами ClearCase, расположенными в Штатах, а именно в штате Иллинойс. Так вот, даже работая через консоль с текстовыми данными, периодически имели некоторые подтормаживание в работе. О запуске графических тулзов удаленно (для диффа или отображения дерева версий, например) речь даже не шла — тупило ужасно. И это при том, что на штатовской стороне канал широченный, у нас тут — тоже не самый маленький. Однако — тормоза были.
            Хотя, повторюсь, при консольной работе и при передаче мелкой дельты — проблема не очень большая получается, да.

            Кстати, есть и смежная проблема — качество связи. Сидя в офисе, команда становится полностью зависимой от провайдера со всеми его обрывами и проф.работами. Конечно, ситуация всё более редкая — всё-таки интернет у нас в стране развивается. Однако нюанс с надежностью всё ещё актуален.
              0
              А это уже косяк CC. У нас он тормозил и когда в соседних городах были, и даже когда на соседних этажах одного здания.
              С Subversion такого не бывает.
                0
                Нет уж, пардон — то были именно тормоза связи, потому что эти же приложения в локальной сети Моторолы, когда я был там в командировке, просто летали.

                То была довольно старая версия СС, не отягощенная современными доработками вроде UCM. А вот уже их тормоза — да, спорить не буду, неоднократно наслышан.
          +1
          Зависит от того, получаем мы инфу одним куском или маленькими частями. Если у нас система контроля версий перебирает маленькие файлы на удаленном компе — то пинг будет о-го-го как влиять.
            0
            Имею древний VSS 6.0 на нынешней работе. В локалке скорость получения Get Latest Version вполне приемлимая, через VPN (из другого района того же города) этот же процесс просто убивает всякое желание работать.
              0
              Оо… СорсСэйф… :) я с него начинал… :)

              Недостаток веток не мешает работе? Скажем, когда надо проверить что-то и сохранить несколько промежуточных версий? Или разработка в проекте линейна и не требует?
                0
                Это последнее, что мешает. Вся работа организована через не так, как надо — то место на сервере заканчивается, то еще что-то уронится. Слава Богу хоть заставили им пользоваться, надеюсь когда на TFS переползем — полегчает.
                  0
                  Как переползете — делись впечатлениями. :)
                    0
                    Если не состарюсь к тому времени :)
            0
            Так вот, в какой-то момент возникает необходимость сделать доступным центральное хранилище локально в одном из центров разработки – для ускорения работы и обхода ограничений по трафику или пропускной способности.


            Очень спорное решение выделить это как основную причину перехода на распределенную систему контроля версий. Например, в делах домашних (университет, coding4fun) пару пытался перейти на subversion, но не получалось; зато попробовав hg, не знаю как работать без него:) очевидно, что центральные хранилище и центры разработки здесь не причем.
              +2
              В моём цикле статей изначально рассматривается работа команды, так что работа человека в режиме «тихо сам с собою», увы, вообще не рассматривается :) Отсюда и первоначальная постановка задачи, для решения которой привлекаются средства.
              +1
              Надо бы добавить Bazaar в тройку ведущих DVCS.
              А вот тема репликации централизованных репозитариев для меня новая (ни разу не сталкивался).
              В некотором смысле это тоже распределенные VCS, да.
              Вообще подозреваю сейчас тут очень мало пользователей ClearCase, я все просил выступить вас в его защиту, а то репутация от слухов у него не очень.

              BTW, я тут буду поднимать тему «DVCS vs. CVCS» на конференции SECR/«Собор или базар: системы контроля версий — централизованные или распределенные?»
                +1
                Базар — да, стоило бы. Просто сейчас он не настолько распространен — git и Hg вывели DVCS в широкие массы.

                Насчет защиты ClearCase — надо реанимировать статью про него, материала есть некоторое количество… Надо браться.

                А конференция… жаль, далековато я :) Буду читать доклады…
                +1
                В случае DVCS несколько сложнее подтвердить авторство коммита. Приходится подписывать каждый коммит закрытым ключом разработчика.
                  0
                  Можно подробнее? О какой именно системе идет речь?
                    +1
                    Да о любой, в общем-то. Дело в том, что в централизованное хранилище требует аутентификацию пользователя при каждом коммите, поэтому записям в changelog-е обычно можно доверять. В DVCS не так: каждый разработчик может писать в свою копию репозитория все, что угодно. Например, накоммитить что-нибудь от чужого имени, а потом отправить дельту другим разработчикам. Цифровые подписи changeset-ов при каждом коммите защищают от этой проблемы (да и от многих других).
                    В hg такая фича реализована с помощью GnuPG (см. описание команды hg sign).
                      0
                      А что говорят сами создатели систем? Как они рекомендуют идентифицировать пользователей? Только прибегая к средствам эл. подписи?

                      А вообще, занятная фича архитектуры… прислали набор изменений — сиди, гадай: от того ли он, кого надо? Ведь получается, что на пользователей, получающих новые изменений даже с более-менее «авторитетного» репозитария, всё равно ложится забота о подтверждении подлинности изменений.
                      Или я не прав?
                        +1
                        Не знаю, если честно, официальной позиции разработчиков разных систем:) Но ЭЦП — не такая уж и плохая идея, раз уж ее сделали стандартной фичей.
                        «Авторитетные» репозитории (те, из которых код раздается пользователям, например), могут проверять подписи сразу при попытке сделать push, чтобы пользователи могли не заморачиваться проверками.
                          0
                          В целом, понятно. Однако, ЭЦП — это хоть и нужный и более-менее стандартный, но всё-таки дополнительный геморрой. Ведь надо настраивать средства поддержки подписи на клиенте и сервере, дописывать скрипты обмена изменениями (хотя бы для автоматической проверки подписи)
                          «Традиционные» же системы от него избавлены в принципе, так уж следует из их архитектуры.

                          Что ж, за всё надо платить.

                          Спасибо за информацию.
                  0
                  Почему бы всех разработчиков с Git'ом просто не заставлять обмениваться данными только с местным сервером. В свою очередь он обменивается кодом с другими серверами. Т.е. грубо говоря между разработчиком и сервером нет дополнительных нод. Имхо, это даст все преимещества распределенной системы + централизацию.
                    0
                    Заставлять можно двумя путями

                    1. Технический — просто сделав так, чтобы все коммиты отправлялись центрально репозиторию. В гите этого не предусмотрено — разработчик должен дать команду на формирование набора изменений и отправить его. Для этого надо написать спец. скрипты и фактически насильно внедрить их всем членам команды — т.е. воспользоваться путем №2

                    2. Организационный — разработчиков обязывают сливать все изменения на центральный сервер. Где обязанность — там и её невыполнение, т.е. нет гарантии, что обязательство не будет обходиться стороной.

                    Отсюда вывод: если хочется централизованным способом сбора изменений, то вместо целого комплекса организационно-технических мер проще воспользоваться централизованными системами :) ведь все остальные базовые операции (ветвление, слияние, метки) — большинство систем делает почти одинаково эффективно, только с некоторыми различиями, связанными с реализацией.
                      0
                      Заставлять программно не надо. Если один разработчик хочет другому дать доступ к какой-то своей локальной ветке, то пусть дает.

                      Просто все тесты, билды и тп должны проходить на центральном сервере. Соответственно, если кто-то залил чужой код (полученный не через сервер), то ему просто за это отвечать.

                      По сути, получается централизованная система с возможностью обмена кодом в обход сервера.
                        0
                        Подобные вещи (центральный билд сервер и т.п.) определяются политиками и процедурами проекта, в частности, СМ-политик, т.е. являются чатью организационных мер.
                        Так что противоречия нет. Просто распределенные системы вводят доп. требования к соблюдению правил проекта.
                        0
                        У распределенных систем есть существенный плюс: не обязательно все свои коммиты отправлять другим. Это позволит разработчикам создавать локально хоть миллион веток и коммитов для тестирования, отладки и т.п. При этом репозиторий, из которого будет собираться билд, будет чист и красив
                          +1
                          Чистота и красота репозиториев системы контроля версий — это последнее, о чем надо думать :)) Ведь они созданы для того, чтобы хранить историю изменений — значит изначально задумываются как средства хранения и обработки болього количества информации.
                          Так что это всё равно, что не давать Гуглу индексировать части вашего сайта только потому, что не хочется захлямлять их поисковые индексы :)
                            0
                            Я бы не стал коммитить в общий репозиторий отладочный код, пусть и в отдельную ветку
                              0
                              Почему? Опозориться боишься? :)))
                              Что плохого-то? Ну, лежит ветка, никому не мешает. Надо отдать всем — вот она, берите, приседать даже не надо, чтобы всем показать. Не надо никому, включая тебя — на здоровье, гнить она точно не начнет, заражая всё вокруг. В крайнем случае прибей её, чтобы глаза не мозолила.

                              Здесь принцип — давайте все изменения, а там разбремся.
                                0
                                По поводу плюсов и минусов распределенных систем написано куча статей. Я вряд ли напишу лучше. Лично мне нравится идея не все переносить в общий репозиторий.
                                  0
                                  Процитирую себя же:
                                  > Какой из подходов лучше, конечно, нельзя сказать сразу и для всех проектов.… Единого решения для всех команд и проектов нет и быть не может.

                                  На то и разнообразие средств, каждой задаче — свой набор инструментов.
                          –1
                          ведь все остальные базовые операции (ветвление, слияние, метки) — большинство систем делает почти одинаково эффективно, только с некоторыми различиями, связанными с реализацией


                          Даже со скидкой на «почти» это очень спорное утверждение. Т.к. многие базовые операции реализованы принципиально по-другому и справляются с ними распределенные системы и центральные очень по-разному.
                            0
                            Лично мне чаще всего пригождаются операции ветвления и слияния. В разных системах они сделаны по-разному.
                            Однако везде они работают достаточно эффективно, чтобы выполнять поставленные задачи — для меня это главное.

                            Конечно, я не сравнивал их по скорости и по занимаемому в базе месту, однако разница в несколько сотен миллисекунд между ветвления в git и в SVN — не критичны.
                              0
                              Я говорю не только и не столько о скорости, сколько о простоте. Ветви в SVN, даже в 1.6 гораздо менее удобны, чем в том же git. Именно это отторгает разработчиков от их использования. Люди не хотят «бренчеваться» до тех пор, пока это возможно. По опыту разработки в нескольких компаниях с SVN вижу, что решение «не коммититься» возникает естественным путем у совершенно несвязанных между собой людей.
                              Я очень надеюсь, что DVCS изменят эту ситуацию. Потому что ситуация, когда средство разработки влияет на workflow не лучшим образом, мне кажется сильно неправильной.
                                –1
                                Тут, конечно, создатели SVN дали маху — видимо, сами они не сильно любили ветки, потому и сделали их поначалу через известное место. Однако они исправляются, такчто всё не так плохо, особенно если использовать нормальные GUI.

                                К слову, самый удобны способ ветвления я видел в ClearCase (в его «true» версии — из консоли и с конфигспеками). Там, установив пару строчек в конфиге своего среза репозитария, можно делать ветку автоматически при чекауте элемента — т.е. ты даже не будешь задумываться о том, что ты делаешь ветку и работаешь с ней.
                                Эх, чувствую, напишу я таки статейку про него :)
                                  0
                                  >К слову, самый удобны способ ветвления я видел в ClearCase (в его «true» версии — из консоли и с конфигспеками). Там, установив пару строчек в конфиге своего среза репозитария, можно делать ветку автоматически при чекауте элемента — т.е. ты даже не будешь задумываться о том, что ты делаешь ветку и работаешь с ней.

                                  т.е. чекаут на ревизию, потом коммит и автоматом ветка создается? это как-то отличается от стандартного поведения hg?
                                    0
                                    Нет, не так. Чекаут элемента — автоматом создается ветка. Чекин — создается версия на ветке. Чекаут-чекин — опять создается версия на этой же ветке.
                                    Чтобы начать работу с другой веткой — достаточно в конфиге изменить название ветки — и всё.
                          0
                          Если пользоваться в git только командами pull, add, commit и push, то это мало чем отличается от, скажем, команд svn update и commit. Кроме того, можно настроить (через hooks) ограничения на перемотку веток (так что ответственные ветки сможет формировать только SCM-инженер).

                          Собственно, хоть я и не имею большого опыта командной git разработки, для
                          отправки патчей в opensource проекты через гит я пользуюсь «центральным» репозиторием у себя дома, куда сливаю изменения оригинальных веток, а уже оттуда сливаю на устройство, которым я в данный момент пользуюсь. При публикации патчей — аналогично, только после домашнего репозитория изменения уходят уже на открытый репозиторий, ссылку на ветку в котором я и передаю автору пропатчиваемого проекта.
                          +2
                          Прежде всего хотел поблагодарить автора за хороший цикл статей. Больше всего нравиться взвешенный (без «максим» и «низложений») подход к описанию конфигурационного менеджмента.

                          Я длительное время использую различные централизованные системы контроля версий (CVS, SVN, Perforce), но недавно приобрел начальный опыт с git. В связи с этим хотел поделиться своим взглядом на выбор СКВ для проекта.

                          Из моего опыта, выбор СКВ всегда диктовался принятыми практиками работы (как инженерными так и управленческими) в команде/проекте. Последние 3 года, команды, с которыми я работал, применяли наборы Agile практик, из которых наибольшее отношение к обсуждаемой теме имеет «Постоянная интеграция» (Continuous integration). Использование указанной практики с централизованной системой версий, современным CI сервером (TeamCity, Hudson, Bamboo) и покрытии модульными и интеграционными тестами позволяло поддерживать основную ветку всегда в рабочем состоянии, готовой к Release Candidate в любой момент времени.

                          В случае с git мы утратили эту способность — разработчики удерживали код на своих станциях и синхронизация кода стала происходить гораздо реже. Команда пришла к выводу, что мы можем добиться частой синхронизации и применения CI к некоторой «собирательной» ветке, но сама природа использования децентрализованной СКВ не подталкивает к этому и вынуждает к применению «административных» мер.

                          Ни в коем случае не умаляю важности децентрализованных СКВ для open-source разработки или для случаев, которые описал автор (Владивосток — США), но в команде, где разработчики коммитят часто и интеграция происходит постоянно я не обнаружил преимуществ децентрализованной СКВ над централизованной.

                          Недавно нашел в Сети статью про аналогичную ситуацию от Мартина Фаулера (Martin Fowler), который разбирая преимущества и недостатки децентрализованных СКВ, смоделировал до боли похожую ситуацию.
                          Для интересующихся вопросом его рассуждения можно почитать в статье FeatureBranch.
                            +1
                            Очень интересное практическое замечания.
                            Я ожидал такой проблемы теоретически,
                            даже имел дискуссии на тему «DVCS vs CI»
                            habrahabr.ru/blogs/development_tools/51477/#comment_1361701
                            где сторонники DVCS утверждали, что проблема надумана, и «вы просто не умеете готовить DVCS и CI».
                            Видимо, проблема таки не надумана.
                              +1
                              Ну у Фаулера про это написано довольно четко:

                              Indeed with a disciplined team, I would usually prefer to use a DVCS on a CI project than a centralized one. With a less disciplined team I would worry that a DVCS would nudge people towards long lived branches.

                              Сторонники DVCS могут спокойно продолжать считать проблему надуманной, а сторонники VCS для CI — проблему реальной. Мне кажется, правы обе стороны в том, что проблема на самом деле будет где-то надуманной, а где-то она будет реальной. И не правы в том, что обобщают.
                                0
                                Согласен, я примерно об этом же написал камраду по поводу орг. и тех. мер. Можно заставить всех коммитить все изменения в центральный репозиторий — в конечном счете всё зависит от общей культуры команды.
                                0
                                Прочел ваши комментарии на тему «DVCS vs CI». Полностью согласен с тем, что с помощью различных «внешних» воздействий можно попытаться решить проблему «integration без continuous», но это определенно будут компромисные решения.

                                Всем, кто интересуется вопросом противостояния двух парадигм систем контроля вресий, рекоммендую ознакомиться с комментариями belonesox приведенными выше.
                                0
                                Спасибо за развернутый коммент!
                                Статья интересная, за неё тоже спасибо.

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое