суббота, 21 ноября 2009 г.

Введение в Mercurial. Часть 1. Распределенные системы контроля версий (DVCS).

Здравствуйте, уважаемые!
Решил написать развернутый цикл статей про Мерк, так как судя по общению с товарищами - как то не очень народ его принимает. Вот буду делиться своим опытом и познаниями. Будет несколько статей, в одну все естественно не влезет. Сегодня просто про распределенные системы контроля версий. Что это и с чем едят.

Думаю что с классическими централизованными системами контроля версий (Subversion, CVS) знакомы уже почти все - есть выделенное специальное хранилище называемое репозиторий, в котором хранятся исходники некоторого проекта, и вся история изменений. И вот к этому хранилищу обращаются попеременно все работающие над проектом.
И вроде бы казалось все замечательно, но не так то все просто. Возникает целая куча проблем, как раз связанная с тем, что репозиторий один, и все в него пытаются закачивать свои исходники.
На мой взгляд главная проблема, к которой постепенно приходят все группы разработчиков - это проблема "длинных коммитов", то есть, в больших командах возможно коммитить только большие части кода, которые покрыты тестами и могут уже использоваться. Тому много причин, но главное - страх поломать что-то готовое в репозитирии, что кем-то используется. Где хранить ваши проходные коммиты не совсем понятно. Есть конечно бранчи, но  в svn это довольно жестокая штука, по крайней мере судя по отзывам использующих людей.

И вот появилась немного более сложная концепция - распределенные системы. Давайте посмотрим на локальную копию svn'a. при выполнении чекаута - у нас в каждом каталоге находится .svn - каталог, в котором хранится копия из репозитория. То есть, в снятом чекаутом наборе каталогов и файлов приходит и точная копия внешнего репозитория. Именно этот принцип и эксплуатируется нещадным образом в распределенных системах - у каждого пользователя есть свой локальный репозиторий, причем вовсе необязательно один. При этом то, что в практике svn назвается коммитом и апдейтом выполняется в свой локальный репозиторий.
За счет локальности коммитов достигается большая гранулярность - теперь можно коммитить не опасаясь поломать чужой код, да и весь проект, при этом вы всегда знаете, что история сохраняется, даже в том случае если вы не имеете доступа к основному репозиторию, например, в случае остуствия доступа в интернет.
Понятие основного репозитория в случае распределенных систем контроля довольно условное. Он основной, потому что некто его так назвал. Ничто не мешает вам взять и забрать обновления лично у Васи Пупкина, а ему у вас, да и отправить свои обновления другому - тоже невелика проблема. Естественно если это позволяют настройки прав доступа. Таким образом получаем, что в распределенных системах отсутствует строгая иерархичность - все репозитории равны, и рядом с каждым репозиторием может быть размещена собственная рабочая копия, хотя и не обязательно.
Смотря на такую структуру, возможность локальных коммитов, возможность синхронизации состояния репозитория с кем угодно создается ощущение, что исходники превратятся в кашу, и на определенном этапе, причем совсем недалеком от начала, уже невозможно будет как-то получить адекватное их состояние. На самом деле все не так страшно. Мощнейшей вещью распределенных систем контроля версий - является ветвление. При этом это не ветвление Subversion, это действительно настоящее, удобное и понятное ветвление и слияние. В DVCS, ну по крайней мере в Mercurial (хотя догадываюсь что и в Git и в Bazaar) ветвление это повседневная операция, это в принципе основа контроля версий в данном случае. И реализована она абсюлютно логично и понятно, и действительно проста в использовании.
Для меня решающим фактором при принятии решения о переходе на Mercurial стали именно локальные коммиты (у меня не всегда есть доступ к интернету, а иногда возникает необходимость что-то закоммитить) и настолько мощная поддержка ветвления. Но уже после перехода я был немало удивлен скоростью работы с репозиториями, эквивалент checkout работает очень быстро даже на сверхбольших репозиториях, commit и update - это моментальные операции, действительно моментальные.
Как работать со всем этим хозяйством я буду постепенно писать в следующих постах. Сегодня этакое начало. Следующий пост будет как раз про основы работы с Mercurial. Для тех кто знаком с Subversion не составит труда сделать первые несколько шагов в этом направлении.

Progg it

11 комментариев:

  1. >При этом это не ветвление Subversion, это действительно настоящее, удобное и понятное ветвление и слияние.

    Не могли бы вы подробнее рассказать про недостатки ветвления в Subversion?

    У меня весьма наивное представление о ветвлении в VCS (как централизованных, так и распределённых) — просто не так уж часто приходилось ветвлением/слиянием заниматься.

    Ветвление, afaik, это способ изоляции (новой недоделанной фичи, экспериментов в песочнице отдельного разработчика, etc), при сохранении непрерывного версионирования. Subversion обеспечивает это с помощью механизма ветвей. Mercurial обеспечивает это с помощью клонов репозитория и внутрирепозиторных ветвей.

    Предположим, нет необходимости работать оффлайн, связь с центральным сервером хорошая, машины быстрые.

    В этих условиях — какие есть преимущества у механизмов ветвления Mercurial'а по сравнению с таковыми у Subversion'а?

    Распространённый аргумент, дескать, необходимость мерджа может помешать коммиту, не катит — у разработчика может быть приватная ветвь; sharing кода происходит не через коммиты рабочей копии в общую ветку, а через вливание своей приватной ветки в общую.

    Заранее благодарен за ответ!

    ОтветитьУдалить
  2. > решающим фактором при принятии решения о переходе на Mercurial стали именно локальные коммиты ... и настолько мощная поддержка ветвления

    Я работаю не с мерком, а с гитом. Для меня важен только первый фактор, подозреваю из-за того, что масштабы проекта не настолько велики. И что-то мне кажется, что локальные коммиты можно было бы реализовать и в централизованных скв

    ОтветитьУдалить
  3. Есть конечно бранчи, но в svn это довольно жестокая штука, по крайней мере судя по отзывам использующих людей.

    /.../ ветвление это повседневная операция, это в принципе основа контроля версий в данном случае. И реализована она абсюлютно логично и понятно, и действительно проста в использовании.

    Для меня решающим фактором при принятии решения о переходе на Mercurial стали именно локальные коммиты /.../ и настолько мощная поддержка ветвления.


    Постоянно использую бранчи в SVN именно как повседневную операцию (почти вся разработка протекает в бранчах) и не испытываю никаких проблем при слиянии. Что я делаю не так?

    Что конкретно не так с ветвлением в SVN с Вашей точки зрения? А то уже поднадоела голословная ругань в адрес SVN от людей, которые «слышали отзывы».

    ОтветитьУдалить
  4. " Постоянно использую бранчи в SVN именно как повседневную операцию (почти вся разработка протекает в бранчах) и не испытываю никаких проблем при слиянии. Что я делаю не так? "
    Вы все делаете так. И, действительно, пользоваться бранчами в SVN вполне возможно. Правда до версии 1.5 они вызывали мегааллергию, а до версии 1.6 не было средств работы с перемещенными/переименованными файлами.
    И все это приводит к написанию вот таких гайдов по мержингу: http://habrahabr.ru/blogs/development_tools/57591/ . Но бранчи там есть, и ими действительно можно пользоваться, и с версии 1.6 с ними все так.
    Дело тут в том, что в гит и в меркуриал эти операции значительно проще и быстрее. Сравните это с переездом с CVS на SVN. Когда вы освоите workflow, который предлагает вам Mercurial или Git - вы вряд ли с большим желанием вернетесь обратно.

    ОтветитьУдалить
  5. Правда до версии 1.5 они вызывали мегааллергию, а до версии 1.6 не было средств работы с перемещенными/переименованными файлами.

    Да, до версии 1.5 (вышедшей, кстати, уже почти 2 года назад) в svn не было т.н. merge tracking-а и использование веток было проблемой. Но вряд ли стоит сравнивать hg с тем svn, каким он был 2 года назад. А вот сравнение текущего положения дел с ветками в svn и hg было бы весьма интересным. Впрочем, кажется, что никакого существенного различия тут уже нет.

    в меркуриал эти операции значительно проще и быстрее

    Вся сложность ветвлений состоит в слиянии при наличии конфликтов. Что-то я не слышал про существенный прогресс в этой области.

    ОтветитьУдалить
  6. Да, и еще. В версии 1.6 не было никаких изменений, связанных с переименованием файлов. Переименования и перемещения вполне корректно (с сохранением истории файла) обрабатывались еще в версии 1.4, насколько я помню. Если я не прав, то интересует пруфлинк.

    ОтветитьУдалить
  7. Немного подумав, я вроде бы понял, что Вы имели в виду под фразой «до версии 1.6 не было средств работы с перемещенными/переименованными файлами». Вероятнее всего, имелось в виду отслеживание случаев т.н. tree conflicts при слиянии векток после перемещения/переименования в них файлов. Это действительно добавлено в версии 1.6. Кстати, как с этим (слияние изменений в переименованном файле) дела в hg?

    ОтветитьУдалить
  8. С этим и в Меркуриал и в Гит все в порядке.
    Заметьте, я никогда не говорил, что SVN - полный отстой, я достаточно адекватен, чтобы понимать, что это весьма неплохая система контроля версий. Однако количество телодвижений, которое нужно совершить для организации ветви, а потом для её слияния значительно больше чем в Mercurial и Git.
    DVCS - это просто достаточно большой шаг вперед, по сравнению с централизованными системами. И этот шаг вперед - это не только отличная поддержка ветвлений, но и множество других хороших вещей, которые в централизованных системах нереализуемы ввиду их концепции. Локальные коммиты, возможность поэкспериментировать в своем репозитории, и уже потом принимать решение - заливать все в общий, или нет. Это просто удобно. Попробуйте!
    И ладно бы, если бы они были платные, но это же не так...

    ОтветитьУдалить
  9. Я очень внимательно присматриваюсь к DVCS, именно поэтому стараюсь читать появляющиеся отзывы их счастливых пользователей.

    Децентрализованность дает разработчикам большую гибкость и мобильность. В то же время, легкость локальных коммитов приводит к появлению неконтролируемых локальных ветвей разработки, что не соответствует нашему внутреннему workflow. Мы постояно ветвимся и каждый может свободно экспериментировать в своих бранчах, но имеющаяся у всех возможность наблюдать за ходом разработки во всех ветвях всем кажется очень полезной. В конце концов бранч можно просто удалить, а занимаемое репозиторием дисковое пространство не является таким уж дорогим ресурсом (и не так уж часто нет доступа к репозиторию). Так что в этом смысле идея DVCS мне как раз не очень нравится.

    Поддержку ветвлений в hg и git все постоянно хвалят, но почему-то сложно найти их аккуратное сравнение с современным состоянием svn. Все говорят «Пробуйте!», но внятно объяснить почему-то не хотят. hg я пробовал локально и особого удобства в выполнении слияний не заметил.

    ОтветитьУдалить
  10. Наличие локальных коммитов не приводит к появлению неконтролируемых ветвей разработки. Никто же не запрещает часто пушить код в общедоступный репозиторий.
    В сравнении с последними версиями Svn (1.6), ветвления практически аналогичны. Единственно - количество телодвижений которые нужно совершить в git и в hg меньше.
    Лично меня hg привлек именно локальностью коммитов - я теперь вряд ли смогу сломать код в общем репозитории, и у меня теперь есть возможность делать частые коммиты, в отличие от централизованных систем.
    Да и скорость работы тоже впечатляющая. Даже по сравнению с быстрым svn.

    ОтветитьУдалить
  11. Лично меня hg привлек именно локальностью коммитов - я теперь вряд ли смогу сломать код в общем репозитории, и у меня теперь есть возможность делать частые коммиты, в отличие от централизованных систем.

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

    Меня больше интересует ситуация с tree conflict в hg и git. Самое неприятное для меня ограничение svn — появление tree conflicts при рефакторинге кода в ветви, когда рефакторинг связан с перемещениями и переименованиями файлов. Вот что, например, произойдет в hg, когда я буду мержить ветвь, в которой были переименования, в основную ветвь, в которой те же файлы оказались отредактированными?

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