Функции системы контроля версий

Желательные функции системы контроля версий, то есть

По большому счету, вы можете начать работать по Trunk-Based Development в любой системе контроля версий, которая позволяет делать атомарные коммиты (спойлер: после CVS эта возможность есть во всех системах контроля версий). Хотя, их основное различие - продуктивность и то, как мы ими управляем.

Продуктивность

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

Под скоростью мы, в первую очередь, подразумеваем две вещи:

  1. Скорость, с которой мы можем подтягивать/обновлять/синхронизировать изменения на удаленном сервере.
  2. Скорость, с которой мы можем фиксировать/отправлять изменения обратно на удаленный сервер.

И еще три второстепенные вещи:

  1. Улучшенное слияние кода
  2. Code Review
  3. Continuous Integration

Скорость подтягивания/обновления/синхронизации изменений

Если вы переходите на какую-нибудь ветку в проекте (checkout), которую вы скачивали какое-то время назад, то в этой ветке могут появиться изменения, которые вам надо будет подтянуть/синхронизировать с сервера, т.е. обновить текущую версию кода в этой ветке. Если вы быстро выполните два обновления ветки подряд, то второе, скорей всего, будет бесполезным. Время, затраченное системой контроля версий на определение того, что из удаленного главного репозитория больше ничего не нужно скачивать, определяет то, насколько быстрой явлетяся эта система.

Технологии, которые хранят head revision при смене ветки и больше ничего не делают, обычно должны проходиться по всем папкам и искать изменения в файлах, а затем проверять каждое изменение на сервере. На этой технологии построена Subversion и ее предшественник CVS. Если мы объединим все запросы к серверу на проверку изменений в один общий запрос, то это ускорит работу, но все равно будут проседания по скорости в связи с шириной и глубиной структуры проекта. Perforce делает операцию быстрее, потому что серверная сторона всегда готова к синхронизации, сохраняя ваше дерево и ту ревизию, которая у вас есть для каждого файла в ОЗУ. Это делается за счет поддержки битов, доступных только для чтения, для файлов (обязательно используйте IDE, которая обрабатывает взаимодействия Perforce в фоновом режиме). Perforce может быть намного быстрее в этом последовательном тесте скорости извлечения/обновления/синхронизации, потому что он уже знает ответ на вопрос про текущий статус файла и надо ли его обновлять.

CVS, Subversion and Perforce предлагают вам выбрать проверяемый подкаталог. В ситуации с монорепозиторием вам это очень хорошо подошло бы. По крайней мере, если бы вы рекурсивно разместили службы и приложения внутри trunk.

Git и Mercurial имеют единую точку получения (операция «клонирования» в Git) для всего репозитория. Также в этих двух системах контроля версий нет проверки поддиректорий. Все коммиты с момента последнего обновления репозитория будут скачаны. Это происходит до обхода каталога для определения того, что изменилось локально. Таким образом, эта операция извлечения выполняется очень быстро - все даныне уже получены, а содержимое на стороне сервера уже заархивировано и в значительной степени готово к скачиванию. Это будет иметь место даже в тех случаях, когда конкретный файл был изменен десятки раз с тех пор, как вы в последний раз скачали его его с помощью операции синхронизации. Вы можете подумать, что это долго, но на практике Git невероятно быстр.

Скорость коммитов и отправки кода на сервер

У инструментов, которые мы считаем пригодными для работы, более-менее равные возможности в плане скорости коммитов и отправки кода на сервер.

Subversion и Perforce отправляют на сервер разницу в измененных файлах. Некоторые действия, например обход каталога, могут замедлить эту операцию. Для этих операций мы не сможем избежать большого количества сетевых запросов.

Git и Mercurial делают то же самое, но до того, как вы отправите свой код в удаленное хранилище (push), вы зафиксируете код локально (commit) - это невероятно быстро. Прежде чем вы отправите сообщение в общее удаленное хранилище, Git и Mercurial сначала предложат вам подтянуть изменения с сервера (pull).

Perforce и Subversion позволят вам фиксировать/отправлять изменения в удаленный репозиторий без локального скачивания последней версии кода (и, кстати, всех промежуточных тоже). Это допустимо только в том случае, если между строками кода, которые вы правили, и актуальной версией кода на сервере нет никакх конфликтов.

Perforce, кстати, действует немного хитро - он использует преимущество “read-only” бита и, следовательно, уже знает, какие файлы определенно не изменились между удаленным хранилищем и локальной рабочей копией кода. Однако он все еще кажется медленнее, чем должен быть.

Three-way merge tools

Если у разработчиков (надеюсь, что они программируют в парах) есть незавершенная работа в их рабочей копии кода, то им нужно будет научиться:

  1. Арбитражу при слиянии для кода, который они хотят отправить в trunk на удаленном сервере.
  2. Арбитражу при получении изменений, которые они получают из trunk на удаленном сервере. Как видите, команды разработчиков на основе Trunk-Based Development взаимодействуют все чаще. Хотя это небольшие слияния, и они неявно сливаются с вашей рабочей копией.

Инструмент трехстороннего слияния Perforce (P4Merge) сам по себе достаточно хорош, чтобы быть привлекательным для команд, использующих другие технологии VCS. Для других технологий P4Merge - это просто настройка конфигурации, которую нельзя использовать.

Семантическое слияние - это следующий шаг в науке об управлении версиями. См. Plastic SCM.

Code Review

Интегрированный обзор кода оказался важнейшей функцией в системах контроля версий. Это должно было быть ясно с того момента, как Mondrian был представлен Гвидо ван Россумом (мистер Python) в разрекламированном Google ‘техническом разговоре’ в 2006. У Mondrian есть такая функция, как code review перед отправкой кода, и в какой-то степени это стало похоже на игру. Раньше Google использовал Perforce (они перешли на технологию, которая была разработана внутри компании, в 2012 году), и у него не было встроенного инструмента для code review, так что Google пришлось перейти на Mondrian, который был окончательный результатом нескольких лет разработки. Создаваемый Mondrian тесно увязал анализ кода с почасовой деятельностью разработчиков в trunk.

GitHub (не Git) был следующим инструментом для мира разработчиков, который не был связан с Google, со встроенным инструментом проверки кода (и рабочим процессом). Опять же это было эффективно выполнить предварительный commit - или, по крайней мере, сделать commit в master ветке.

Были (и есть) другие технологии для code review, такие как Crucible (Atlassian), UpSource (JetBrains), Gerrit, Phabricator, но ключевым моментом является интеграция в платформу. GitLab и RhodeCode - развивающиеся платформы.

Можете почитать Game Changers - Google’s Mondrian и Game Changers - GitHub’s Pull Requests.

Continuous Integration тестирование

Это идет рука об руку с возможностью code review. Серверы CI запускаются для кода, который был отправлен в ветку для code review, а потом для кода, который был отправлен в ветку в процессе code review, и проверяют изменения. Обычная сборка (а может и некоторые дополнительные шаги, которые выполняются после сборки и выдают результат тем, кто смотрит код) в Facebook имеет Соглашение об уровне обслуживания, согласно которому тестирование кода должно быть выполнено в течение десять минут после того, как код был помещен в очередь «требуется проверка кода».

Реальность платформ VCS сегодня такова, что они предоставляли hooks (скорее всего, webhooks) только для других серверов CI. Лучшие комбинации системы контроля версий и сервера CI делают это для любой из задействованных веток, включая ветки проверки кода(forks).

Управление

Оказывается, предприятиям нравится возможность разделять разрешения и устанавливать разрешения на чтение и запись во всех своих репозиториях.

Детализированные разрешения

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

Чем крупнее предприятие, тем больше вероятность того, что у них будут более мелкие разрешения. Например, разрешение «можно отправить commit в trunk, но нельзя создавать ветку версии», очень часто встречается в корпорациях, где команды работают по Trunk-Based Development и работают с релизными ветками. Не все системы контроля версий поддерживают это. Git, например, эту функцию не поддерживает, но есть разные экспериментальные решения на базе git, в которых эта функция добавлена. Однако, в действительности вы не можете помешать людям создавать ветки в распределенной системе контроля версий, но вы можете запретить им отправлять эти ветки в общий репозиторий.

Более того, некоторые предприятия захотят установить разрешения на уровне каталогов внутри ветки в репозитории. Это может быть так же просто, как шлюз, чтобы гарантировать, что процесс соблюдается при проверке, но также может быть и для защиты некоторые секреты реализации Monorepo. Последнее противоречит некоторым идеалам “общего владения кодом” современная программная инженерия.

Deeper still, some enterprises will want to set permissions down the directory level within a branch within a repository. This could be as simple as a gate, to ensure that process is adhered to around checkins, but could also be to guard some secrets in a Monorepo implementation. That last is counter to some of the “common code ownership” ideals of modern software engineering though.

Size / Scale

Many teams, particularly those with Monorepo configurations or large binary files (like Games companies), want to have limitless server-side storage for their repository. Git and Mercurial are inching towards bigger and bigger capacity, but there are still a few snafus to work through - how to cleanly/safely reduce the size of the client side clone history (while still being able to push changes back to the server) is a challenge.

Microsoft released Git Virtual File System (GitVFS GVFS VFS for Git) in early 2017, to layer on some of the things they had become used to in the in-house recompilation of Perforce (SourceDepot - used from 1998 to 201x), as well as native VCS of their commercial offering Team Foundation Server (TFS).