Ниже я рассмотрю что такое системы контроля версий, зачем они нужны, основные вехи в развитии систем контроля версий с открытым исходным кодом и конечно примеры. Распределенная система контроля версий Bazaar более подробно рассмотрена в отдельной статье.
Зачем нужен контроль версий?
В последнее время файлы являются конечным результатом для многих профессий, здесь можно назвать писательскую деятельность, научные работы и конечно разработку программного обеспечения. Тратится много времени и сил на разработку и поддержку этих файлов и никто не хочет, чтобы пришлось тратить еще больше времени и сил на восстановление данных потерянных в результате каких-либо изменений.
Представим, что программист разрабатывает проект состоящий из одного небольшого файла. После выпуска первой версии проекта перед ним встает непростой выбор: необходимо исправлять проблемы о которых сообщают пользователи первой версии и в тоже время разрабатывать что-то новое для второй. Даже если надо просто исправлять возникающие проблемы, то велика вероятность, что после какого-либо изменения проект перестает работать и надо определить, что было изменено чтобы было проще локализовать проблему. Также желательно вести какой-то журнал внесенных изменений и исправлений, чтобы не делать несколько раз одну и туже работу.
В простейшем случае вышеприведенную проблему можно решить хранением нескольких копий файлов, например, один для исправления ошибок в первой версии проекта и второй для новых изменений. Так как изменения обычно не очень большие по сравнению с размером файла, то можно хранить только измененные строки используя утилиту diff и позже объединять их с помощью утилиты patch. Но что если проект состоит из нескольких тысяч файлов и над ним работает сотня человек? Если в этом случае использовать метод с хранением отдельных копий файлов (или даже только изменений) то проект застопорится очень быстро.
Как раз для решения вышеприведенных проблем и служат системы контроля версий, которые решают следующие проблемы:
- Хранение версий файлов, причем обычно хранятся только изменения между предыдущей и текущей версией и таким образом хранилище не растет слишком быстро;
- Возможность получить любые предыдущие версии хранимых файлов;
- Просмотр изменений внесенных между заданными в запросе версиями;
- Сохранение и просмотр комментариев и авторов к внесенным изменениям;
Краткая история систем контроля версий с открытым исходным кодом.
Пропуская все ранние системы, которые могут быть интересны только историкам, рассмотрим сразу RCS, затем основанную на ней CVS, далее систему которая стала ее последователем - Subversion и в итоге обратимся к одному из представителей новой волны распределенных систем контроля версий - Bazaar.
RCS
RCS (Revision Control System, Система контроля ревизий) была разработана в начале 1980-х годов Вальтером Тичи (Walter F. Tichy). Система позволяет хранить версии только одного файла, таким образом управлять несколькими файлами приходится вручную. Для каждого файла находящегося под контролем системы информация о версиях хранится в специальном файле с именем оригинального файла к которому в конце добавлены символы ',v'. Например для файла file.txt версии будут храниться в файле file.txt,v. Для хранения версий система использует утилиту diff, то есть хранятся только изменения между версиями.
Рассмотрим пример сессии с RCS (знак $ здесь и далее обозначает приглашение операционной системы). Когда мы хотим положить файл под контроль RCS мы используем команду ci (от check-in, регистрировать):
$ ci file.txt
Данная команда создает файл file.txt,v и удаляет исходный файл file.txt (если не сказано этого не делать). Также эта команда запрашивает описание для всех хранимых версий. Так как исходный файл был удален системой мы должны запросить его обратно, что бы вносить изменения. Для этого мы используем команду co (от check-out, контролировать):
$ co file.txt
Эта команда вынимает последнюю версию нашего файла из file.txt,v. Теперь мы можем отредактировать файл file.txt и после того как закончим изменения опять выполнить команду ci для того что бы сохранить новую измененную версию файла:
$ ci file.txt
При выполнении этой команды система запросит у нас описание изменений и затем сохранит новую версию файла.
Хотя RCS соответствует минимальным требованиям к системе контроля версий она имеет следующие основные недостатки, которые также послужили стимулом для создания следующей рассматриваемой системы:
- Работа только с одним файлом, каждый файл должен контролироваться отдельно;
- Неудобный механизм одновременной работы нескольких пользователей с системой, хранилище просто блокируется пока заблокировавший его пользователь не разблокирует его;
CVS
CVS (Concurrent Versions System, Система совместных версий) пока остается самой широко используемой системой, но быстро теряет свою популярность из-за недостатков которые я рассмотрю ниже. Дик Грун (Dick Grune) разработал CVS в середине 1980-х. Для хранения индивидуальных файлов CVS (также как и RCS) использует файлы в RCS формате, но позволяет управлять группами файлов расположенных в директориях. Также CVS использует клиент-сервер архитектуру в которой вся информация о версиях хранится на сервере. Использование клиент-сервер архитектуры позволяет использовать CVS даже географически распределенным командами пользователей где каждый пользователь имеет свой рабочий директорий с копией проекта.
Как следует из названия пользователи могут использовать систему совместно. Возможные конфликты при изменении одного и того же файла разрешаются тем, что система позволяет вносить изменения только в самую последнюю версию файла. Таким образом всегда рекомендуется перед заливкой своих изменений обновлять свою рабочую копию файлов на случай возможных конфликтующих изменений. При обновлении система вносит изменения в рабочую копию автоматически и только в случае конфликтующих изменений в одном из мест файла требуется ручное исправление места конфликта.
CVS также позволяет вести несколько линий разработки проекта с помощью ветвей (branches) разработки. Таким образом, как уже упоминалось выше, можно исправлять ошибки в первой версии проекта и параллельно разрабатывать новую функциональность.
Рассмотрим небольшой пример сессии с CVS. Прежде всего надо импортировать проект в CVS, это делается с помощью команды import (импортировать):
$ cd some-project $ cvs import -m "New project" path-in-repository none start
Здесь опция -m позволяет задать описание изменений прямо в командной строке и если ее опустить, то будет вызван текстовый редактор. Далее указывается путь по которому проект будет храниться в репозитории (path-in-repository в нашем случае) и после него две метки: метка разработчика (может пригодится в случае использования CVS для работы над проектами разработанными кем-то другим) и метка проекта.
После того как мы залили наш проект в репозиторий необходимо создать новый директорий в котором будет находится рабочая копия проекта под контролем CVS и загрузить проект с помощью команды checkout (контроль), или сокращенно co:
$ cd some-working-dir $ cvs checkout path-in-repository
Для команды checkout мы указываем путь к нашему проекту в репозитории который мы указывали выше в команде import.
Теперь мы можем внести в проект изменения и залить их в репозиторий с помощью команды commit (совершить изменения), или сокращенно ci:
$ cvs commit -m "Some changes"
Также как и для команды import мы указываем комментарий к нашим изменениям с помощью опции -m.
Если мы хотим обновить наш рабочий директорий новой версией проекта из репозитория мы используем команду update (обновить), или сокращенно up:
$ cvs update
CVS использовалась большим количеством проектов, но конечно не была лишена недостатков которые позднее привели к появлению следующей рассматриваемой системы. Рассмотрим основные недостатки:
- Так как версии хранятся в файлах RCS нет возможности сохранять версии директорий. Стандартный способ обойти это препятствие - это сохранить какой-либо файл (например, README.txt) в директории;
- Перемещение, или переименование файлов не подвержено контролю версий. Стандартный способ сделать это: сначала скопировать файл, удалить старый с помощью команды cvs remove и затем добавить с его новым именем с помощью команды cvs add;
Subversion
Subversion (SVN) был разработан в 2000 году по инициативе фирмы CollabNet. SVN изначально разрабатывался как "лучший CVS" и основной задачей разработчиков было исправление ошибок допущенных в дизайне CVS при сохранении похожего интерфейса. SVN также как и CVS использует клиент-сервер архитектуру. Из наиболее значительных изменений по сравнению с CVS можно отметить:
- Атомарное внесение изменений (commit). В случае если обработка коммита была прервана не будет внесено никаких изменений.
- Переименование, копирование и перемещение файлов сохраняет всю историю изменений.
- Директории, символические ссылки и мета-данные подвержены контролю версий.
- Эффективное хранение изменений для бинарных файлов.
Рассмотрим примеры команд, хотя надо заметить, что большинство из них практически повторяют команды CVS. Что бы использовать проект с SVN его надо сначала импортировать в репозиторий с помощью команды import (импортировать):
$ cd some-project $ svn import -m "New project" path-in-repository
В отличие от CVS не нужно указывать метки разработчика и проекта, которые не часто использовались на практике.
Теперь нам нужно создать рабочую копию проекта с помощью команды checkout (контроль), или co:
$ cd some-working-dir $ svn checkout path-in-repository
После внесения изменений мы используем команду commit (совершить изменения) , или ci для сохранения изменений в репозитории:
$ svn commit -m "Some changes"
И для обновления рабочей копии проекта используется команда update (обновить), или up:
$ svn up