Модели версионирования

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

Проблема разделения файлов

Всем системам контроля версий приходится решать одну и ту же основную проблему: как предоставить пользователям возможность совместного использования информации, при этом, не позволяя им наступать друг другу на пятки? Пользователи могут просто непреднамеренно перезаписать в хранилище изменения друг друга.

Рассматриваемую ситуацию иллюстрирует Рисунок 1.2, «Проблема потери изменений». Допустим у нас есть два со-разработчика Гарри и Салли. Они вдвоем решили одновременно поредактировать один и тот же файл из хранилища. Если первым свои изменения в хранилище сохранит Гарри, то возможно, что (несколькими минутами позже) Салли может непреднамеренно перезаписать их своей новой версией файла. Несмотря на то, что версия файла Гарри не будет полностью потеряна (так как система помнит каждое изменение) внесенные Гарри изменения не будут отражены в новой версии файла Сэлли, потому что, начиная, она, не видела изменения Гарри. Работа Гарри фактически потеряна — или, по крайней мере, отсутствует в последней версии файла — по случайности. Как раз этой ситуации мы и хотим избежать!

Рисунок 1.2. Проблема потери изменений

Проблема потери изменений

Модель Блокирование-Изменение-Разблокирование

Для того, что бы несколько авторов не мешало друг другу многие системы управления версиями применяют модель блокирование-изменение-разблокирование. Эта модель запрещает одновременное редактирование файла несколькими пользователями. Эксклюзивность доступа гарантируется блокировками. Перед началом редактирования Гарри должен «заблокировать» файл. Если файл заблокировал Гарри, Салли уже не сможет его заблокировать и не сможет внести в него изменения. Ей остается только читать файл и ждать пока Гарри закончит свои изменения и снимет свою блокировку. После того как Гарри разблокирует файл, файл сможет получить Салли, заблокировать его и начать редактирование. Рисунок 1.3, «Модель блокирование-изменение-разблокирование» демонстрирует это простое решение.

Рисунок 1.3. Модель блокирование-изменение-разблокирование

Модель блокирование-изменение-разблокирование

Проблемой модели блокирование-изменение-разблокирование является то, что она немного ограниченная и часто доставляет неудобства пользователям:

  • Блокирование может вызвать проблемы администрирования. Иногда Гарри заблокирует файл, а затем забудет об этом. Между тем, ожидая редактирования файла, у Салли будут связаны руки. А Гарри уехал в отпуск. Теперь Салли, для снятия блокировки Гарри, нужно обращаться к администратору. Ситуация заканчивается не нужной задержкой и потерянным временем.

  • Блокирование может вызвать излишнюю пошаговость. Что если Гарри редактирует начало текстового файла, а Салли нужно отредактировать концовку этого же файла? Эти изменения совсем не перекрываются. Они могли бы легко редактировать файл одновременно и никаких особенных проблем это не вызвало бы, предполагая корректное слияние изменений. Блокирование файла в такой ситуации не требуется.

  • Блокирование может вызвать ложное чувство безопасности. Предположим, что Гарри блокирует и редактирует файл А, в то время как Салли одновременно блокирует и редактирует файл В. Но допустим, что А и В зависят друг от друга и сделанные в каждом изменения семантически не совместимы. Неожиданно А и В больше не работают вместе. Блокирующая система бессильна в предотвращении проблемы — вместо этого она обеспечила ложное чувство безопасности. Для Гарри и Салли просто вообразить, что, блокируя файлы каждый начинает безопасную изолированную задачу и не беспокоиться об обсуждении их несовместимых изменений заранее. Зачастую, блокирование подменяет настоящее общение.

Модель Копирование-Изменение-Слияние

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

Вот пример. Скажем и Гарри и Салли создали копированием из хранилища рабочие копии одного и того же проекта. Они работают одновременно и в своих рабочих копиях вносят изменения в один и тот же файл А. Первой свои изменения в хранилище сохраняет Салли. Когда позже Гарри попытается сохранить свои изменения, хранилище проинформирует его о том, что его файл А устарел. Другими словами, файл А каким то образом изменился со времени, когда он его последний раз копировал. Поэтому Гарри просит свой клиент слить любые изменения из хранилища в его рабочую копию файла А. По счастливому совпадению, изменения Салли не перекрываются с его собственными; после объединения обоих наборов изменений он сохраняет свою рабочую копию обратно в хранилище. Рисунок 1.4, «Модель копирование-изменение-слияние» и Рисунок 1.5, «Модель копирование-изменение-слияние (продолжение)» показывают этот процесс.

Рисунок 1.4. Модель копирование-изменение-слияние

Модель копирование-изменение-слияние

Рисунок 1.5. Модель копирование-изменение-слияние (продолжение)

Модель копирование-изменение-слияние (продолжение)

А что если изменения Салли перекрываются с изменениями Гарри? Что тогда? Эта ситуация называется конфликтом и, как правило, это не является большой проблемой. Когда Гарри просит свой клиент слить последние изменения хранилища в рабочую копию, его копия файла А как-то помечается как находящаяся в состоянии конфликта: у него будет возможность видеть оба набора конфликтующих изменений и вручную сделать между ними выбор. Помните, что ПО не может автоматически разрешать конфликты; только человек способен к пониманию и выполнению осмысленного выбора. Разрешив вручную перекрывающиеся изменения - возможно, после обсуждения с Салли — он может безопасно сохранить объединенный файл обратно в хранилище.

Модель копирование-изменение-слияние может выглядеть немного хаотично, однако, на практике она отлично работает. Пользователи могут работать параллельно, не тратя время на ожидание друг друга. При работе над одними и теми же файлами оказывается, что большинство параллельно вносимых изменений совсем не перекрываются; конфликты бывают редко. И время, которое было потрачено на разрешение конфликтов, как правило, значительно меньше времени отнимаемого блокирующей системой.

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