Распределённая система управления версиями

undefined

Распределённая система управления версиями ( распределённый контроль версий, распределённая система ревизий) — это разновидность системы управления версиями, которая используется в процессе разработки программного обеспечения. При этом подходе вся кодовая база и её история изменений хранятся локально на компьютере каждого разработчика[1]. По сравнению с централизованными системами управления версиями, такой подход автоматически поддерживает операции ветвления (branching) и слияния (merging), ускоряет большинство действий (кроме отправки — push и получения — fetch), обеспечивает возможность работы офлайн, а также не требует единой точки для хранения резервных копий.[1][2][3] Git — одна из самых популярных в мире систем управления версиями[4] и реализует распределённый принцип.

В 2010 году автор публикаций по программной инженерии Джоэл Спольски (англ. Joel Spolsky) охарактеризовал распределённые системы управления версиями как «одно из самых значительных достижений в технологиях программной разработки за последнее десятилетие»[2].

Сравнение распределённых и централизованных систем

Распределённые системы управления версиями (около. англ. Distributed Version Control System, DVCS) используют одноранговый подход, противоположный клиент-серверной архитектуре централизованных систем. В распределённом контроле версий репозитории синхронизируются между собой путём обмена патчами. Централизованной версии кодовой базы не существует — вместо этого каждый пользователь имеет как рабочую копию, так и полный архив истории изменений.

Преимущества распределённых систем управления версиями перед централизованными:

  • Позволяют эффективно работать вне сети (офлайн).
  • Наиболее частые операции (например, фиксация изменений (commit), просмотр истории, откат изменений) выполняются быстрее, так как не требуют обращения к центральному серверу.[5] Связь с другими пользователями необходима только во время обмена изменениями.
  • Поддерживают изолированную работу: пользователь может создавать и использовать собственные черновики изменений, не публикуя их.
  • Рабочие копии также служат резервными, снижая зависимость от одной машины и уменьшая риск потери из-за единой точки отказа[5].
  • Позволяют использовать разные модели разработки, например, разветвлённые ветвления или модель «Командир/Лейтенант» (Commander/Lieutenant)[6].
  • Позволяют централизованно контролировать «публичную» (релизную) версию проекта.
  • В проектах с открытым исходным кодом намного проще создавать «ответвления» (форки) при возникновении конфликтов или разногласий.

Недостатки распределённых систем управления версиями относительно централизованных:

  • Первоначальное клонирование репозитория (checkout) проходит дольше, поскольку копируется вся история и все ветви.
  • Отсутствие механизма блокировки файлов, характерного для многих централизованных систем управления версиями, затрудняет работу с несравниваемыми бинарными файлами (например, графическими ресурсами), цельными сложными бинарными или XML-наборами (например, офисными документами, PowerBI, пакетами SQL Server Data Tools BI и др.).
  • Требуется больше места на диске, так как у каждого разработчика хранится полный архив изменений кодовой базы[7].
  • Из-за наличия полного исходного кода у всех участников возрастает риск несанкционированного доступа к данным.

Некоторые изначально централизованные системы впоследствии реализовали и распределённые возможности. Например, Team Foundation Server и Visual Studio Team Services поддерживают оба режима благодаря интеграции с Git.

В то же время ряд новых распределённых систем добавляют функции для уменьшения времени клонирования и снижения требований к дисковому пространству. Например, разработанная Microsoft для огромных репозиториев система Virtual File System for Git загружает файлы в локальный репозиторий по требованию, по мере необходимости[8].

Модель работы

Распределённая схема управления версиями чаще используется в крупных проектах с частично независимыми разработчиками, например, в ядре Linux. Она позволяет разработчикам работать в отдельных ветках и создавать изменения, которые затем могут быть приняты, отклонены или проверены другими разработчиками[9]. Такой подход позволяет гибко разветвлять и адаптировать исходный код под разные задачи, создавая собственные ответвления (форки). Кроме того, разработчики могут локально клонировать репозиторий и фиксировать изменения в собственной копии, прежде чем отправлять их в основной репозиторий[10]. Это облегчает отслеживание изменений до внесения их в основную ветку и делает распределённую модель более удобной для больших команд и проектов.

Центральные и форкнутые репозитории

В полностью распределённом проекте (например, Linux), каждый участник поддерживает свою копию проекта и при необходимости обменивается изменениями с другими разработчиками напрямую. Таким образом, репозиторий проекта может со временем расходиться (в случае прекращения работы с изменениями других участников — форкаться), и развивается конкурирующее множество версий.

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

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

Pull-запросы

Вклад в открытый проект с использованием распределённой системы управления версиями обычно вносится через pull-запрос (или merge-запрос)[11]. Разработчик формирует запрос на принятие изменений (pull request), после чего команда проекта может принять внесённые изменения в основной исходный код[12].

Pull-запрос содержит сопроводительную дискуссию, где участники обсуждают предлагаемые изменения до их слияния. Все pull-запросы публичны для пользователей с доступом к репозиторию, и могут быть как приняты, так и отклонены[13].

После одобрения pull-запрос объединяется с проектом. В зависимости от рабочего процесса, до публикации в основной ветви изменения могут дополнительно тестироваться или помещаться в специализированную ветку[12][14]. Кроме того, для проверки новых изменений часто используются системы автоматического тестирования и инструменты непрерывной интеграции.

История

Среди первых открытых распределённых систем управления версиями были такие проекты, как Arch, Monotone и Darcs. По-настоящему массовую популярность среди свободных альтернатив системы управления версиями получили с появлением Git и Mercurial.

В 2002—2005 годах для сопровождения разработки ядра Linux использовалось программное обеспечение BitKeeper[15]. Разработка Git, ставшего впоследствии самой популярной системой управления версиями в мире[4], началась после того, как компания, разработавшая BitKeeper, отменила бесплатную лицензию для Линуса Торвальдса и ряда других разработчиков ядра Linux[15].

Примечания

Ссылки