# Первое поколение
Системы контроля версий первого поколения отслеживали изменения в отдельных файлах, а редактирование поддерживалось только локально и одним пользователем за раз. Системы строились на предположении, что все пользователи будут заходить по своим учётными записям на один и тот же общий узел Unix.
- SCCS (Source Code Control System)
- RCS (Revision Control System)
# Второе поколение
В VCS второго поколения появилась поддержка сети, что привело к централизованным хранилищам с "официальными" версиями проектов. Это был значительный прогресс, поскольку несколько пользователей могли одновременно работать с кодом, делая коммиты в один и тот же центральный репозиторий. Однако для коммитов требовался доступ к сети.
- CVS (Concurrent Versions System)
- SVN (Apache Subversion)
# Третье поколение
Третье поколение состоит из распределённых VCS, где все копии репозитория считаются равными, нет центрального репозитория. Это открывает путь для коммитов, ветвей и слияний, которые создаются локально без доступа к сети и перемещаются в другие репозитории по мере необходимости.
- Git
- Mercurial
Для контекста, вот график c датами появления этих инструментов:

SCCS (Source Code Control System): первое поколение
SCCS считается одной из первых успешных систем управления версиями. Она была разработана в 1972 году Марком Рочкиндом из Bell Labs. Система написана на C и создана для отслеживания версий исходного файла. Кроме того, она значительно облегчила поиск источников ошибок в программе. Базовая архитектура и синтаксис SCCS позволяют понять корни современных инструментов VCS.
Как и большинство современных систем, в SCCS есть набор команд для работы с версиями файлов:
RCS (Revision Control System): первое поколение
RCS написана в 1982 году Уолтером Тихи на языке С в качестве альтернативы системе SCCS, которая в то время не была опенсорсной.
У RCS много общего со своим предшественником, в том числе:
CVS (Concurrent Versions System): второе поколение
CVS создана Диком Груном в 1986 году с целью добавить в систему управления версиями поддержку сети. Она также написана на C и знаменует собой рождение второго поколения инструментов VCS, благодаря которым географически рассредоточенные команды разработчиков получили возможность работать над проектами вместе.
CVS - это фронтенд для RCS, в нём появился новый набор команд для взаимодействия с файлами в проекте, но под капотом используется тот же формат файла истории RCS и команды RCS. Впервые CVS позволил нескольким разработчикам одновременно работать с одними и теми же файлами. Это реализовано с помощью модели централизованного репозитория. Первый шаг - настройка на удалённом сервере централизованного репозитория с помощью CVS. Затем проекты можно импортировать в репозиторий. Когда проект импортируется в CVS, каждый файл преобразуется в файл истории и хранится в центральной директории: module. Репозиторий обычно находится на удалённом сервере, доступ к которому осуществляется через локальную сеть или интернет.
Разработчик получает копию модуля, который копируется в рабочий каталог на его локальном компьютере. В этом процессе никакие файлы не блокируются, так что нет ограничения на количество разработчиков, которые могут одновременно работать с модулем. Разработчики могут изменять свои файлы и по мере необходимости фиксировать изменения (делать коммит). Если разработчик фиксирует изменение, другие разработчики должны обновить свои рабочие копии с помощью (обычно) автоматизированного процесса слияния перед фиксацией своих изменений. Иногда приходится вручную разрешать конфликты слияния, прежде чем выполнить коммит. CVS также предоставляет возможность создавать и объединять ветви.
SVN (Subversion): второе поколение
Subversion создана в 2000 году компанией Collabnet Inc., а в настоящее время поддерживается Apache Software Foundation. Система написана на C и разработана как более надёжное централизованное решение, чем CVS.
Как и CVS, Subversion использует модель централизованного репозитория. Удалённым пользователям требуется сетевое подключение для коммитов в центральный репозиторий.
Subversion представила функциональность атомарных коммитов с гарантией, что коммит либо полностью успешен, либо полностью отменяется в случае проблемы. В CVS при неполадке посреди коммита (например, из-за сбоя сети) репозиторий мог остаться в повреждённом и несогласованном состоянии. Кроме того, коммит или версия в Subversion может включать в себя несколько файлов и директорий. Это важно, потому что позволяет отслеживать наборы связанных изменений вместе как сгруппированный блок, а не отдельно для каждого файла, как в системах прошлого.
В настоящее время Subversion использует файловую систему FSFS (File System atop the File System). Здесь создаётся база данных со структурой файлов и каталогов, которые соответствуют файловой системе хоста. Уникальная особенность FSFS заключается в том, что она предназначена для отслеживания не только файлов и каталогов, но и их версий. Это файловая система с восприятием времени. Кроме того, директории являются полноценными объектами в Subversion. В систему можно коммитить пустые директории, тогда как остальные (даже Git) не замечают их.
Git: третье поколение
Систему Git разработал в 2005 году Линус Торвальдс (создатель Linux). Она написана в основном на C в сочетании с некоторыми сценариями командной строки. Отличается от VCS по функциям, гибкости и скорости. Торвальдс изначально написал систему для кодовой базы Linux, но со временем её сфера использования расширилась, и сегодня это самая популярная в мире система управлениями версиями.
Git является распределённой системой. Центрального репозитория не существует: все копии создаются равными, что резко отличается от VCS второго поколения, где работа основана на добавлении и извлечении файлов из центрального репозитория. Это означает, что разработчики могут обмениваться изменениями друг с другом непосредственно перед объединением своих изменений в официальную ветвь.
Кроме того, разработчики могут вносить свои изменения в локальную копию репозитория без ведома других репозиториев. Это допускает коммиты без подключения к сети или интернету. Разработчики могут работать локально в автономном режиме, пока не будут готовы поделиться своей работой с другими. В этот момент изменения отправляются в другие репозитории для проверки, тестирования или развёртывания.
Git реализует промежуточный индекс (staging index), который выступает в качестве промежуточной области для изменений, которые готовятся к коммиту. По мере подготовки новых изменений на их сжатое содержимое ссылаются в специальном индексном файле, который принимает форму объекта дерева. Дерево - это объект Git, который связывает блобы с их реальными именами файлов, разрешениями на доступ к файлам и ссылками на другие деревья и таким образом представляет состояние определённого набора файлов и каталогов. Когда все соответствующие изменения подготовлены для коммита, индексное дерево можно зафиксировать в репозитории, который создаёт объект коммит в базе данных объектов Git. Коммит ссылается на дерево заголовков для конкретной версии, а также на автора коммита, адрес электронной почты, дату и сообщение коммита. Каждый коммит также хранит ссылку на свой родительский коммит(-ы), и так со временем создаётся история развития проекта.
Когда ветви перемещаются в удалённые хранилища или извлекаются из них, по сети передаются эти пакетные файлы. При вытягивании или извлечении ветвей файлы пакета распаковываются для создания свободных объектов в репозитории объектов.
Mercurial: третье поколение
Mercurial создан в 2005 году Мэттом Макколлом и написан на Python. Он тоже разработан для хостинга кодовой базы Linux, но для этой задачи в итоге выбрали Git. Это вторая по популярности система управления версиями, хотя она используется гораздо реже.
Mercurial - тоже распределённая система, которая позволяет любому числу разработчиков работать со своей копией проекта независимо от других. Mercurial использует многие из тех же технологий, что и Git, в том числе сжатие и хэширование SHA-1, но делает это иначе.
Когда новый файл фиксируется для отслеживания в Mercurial, для него создаётся соответствующий файл revlog в скрытом каталоге .hg/store/data/. Можете рассматривать файл revlog (журнал изменений) как модернизированную версию файлов истории в старых VCS, таких как CVS, RCS и SCCS. В отличие от Git, который создаёт новый блоб для каждой версии каждого подготовленного файла, Mercurial просто создаёт новую запись в revlog для этого файла. Для экономии места каждая новая запись содержит только дельту от предыдущей версии. Когда достигается пороговое число дельт, снова сохраняется полный снимок файла. Это сокращает время поиска при обработке большого количества дельт для восстановления определённой версии файла.
Source: Habr