Представьте: 1982 год, где-то в Университете Пердью Уолтер Тичи пытается контролировать версии своего кода с помощью перфокарт и молитв. Перенесёмся в сегодняшний день, когда я могу случайно выполнить команду rm -rf
для своего проекта и маниакально смеяться, пока Git воскрешает его. Давайте разберёмся, как мы к этому пришли — с практическими примерами, папиными шутками и по крайней мере одной завуалированной отсылкой к «Звёздному пути».
Эра RCS: когда код хранился в Форт-Ноксе
Система контроля версий (RCS) была оригинальной системой контроля версий, которая обращалась с файлами как с редкими библиотечными книгами — одновременно их мог взять только один человек. Вот как вы могли бы использовать её сегодня (если вам нравится цифровая археология):
# Создание вашего первого цифрового каменного скрипта
$ ci -u important_script.sh
RCS/important_script.sh,v <-- important_script.sh
initial revision: 1.1
Рабочий процесс RCS выглядел так:
- Блокировка файла, будто это последний кусок пиццы.
- Редактирование под пристальными взглядами коллег.
- Возврат с сообщением в журнале вроде «Исправлена ошибка (пожалуйста, работает)». Ключевые инновации:
- Обратные дельты (хранение изменений в обратном порядке, как инструкции IKEA).
- Простые инструменты CLI (
ci
= регистрация,co
= проверка). - Управление версиями на уровне файлов (идеально подходит для одного конфигурационного файла, который вы постоянно ломаете).
Но у RCS были свои особенности:
- Отсутствие атомарных коммитов (представьте себе сохранение каждой буквы в слове отдельно).
- Ад блокировок («Дейв, я знаю, что ты в отпуске — освободи конфигурацию!»).
- Ветвление? Больше похоже на веточки. Разработчики избегали их, как ошибок шаблонов C++.
CVS: первый командный игрок
Когда в 1986 году появилась CVS (система одновременных версий), это было всё равно что перейти от раций к Slack. Наконец-то несколько разработчиков могли ахнуть и работать одновременно! Практическая настройка CVS:
$ cvs import -m "Initial commit" project-name vendor-tag release-tag
$ cvs checkout project-name
Таблица инноваций CVS:
Функция | RCS | CVS |
---|---|---|
Коллаборация | Блокировка одного файла | Множество редакторов |
Поддержка сети | Локальная файловая система | Клиент-сервер |
Отслеживание истории | Для каждого файла | Для всего проекта |
Разрешение конфликтов | «Подождите своей очереди!» | «Слияние с осторожностью» |
Но вскоре разработчики обнаружили тёмную сторону CVS:
- Отсутствие атомарных коммитов (потеря половины изменений было обрядом посвящения).
- Ориентация на файлы, а не на общее видение проекта.
- Пометка релизов была похожа на ловлю кошек Шрёдингера.
Вмешательство Subversion
Когда в 2000 году появился SVN, это было похоже на то, что CVS пошла в школу обаяния. Атомарные коммиты! Контроль версий каталогов! Лучшее ветвление (хотя всё ещё неуклюжее). Давайте отправимся в путешествие во времени:
$ svn checkout http://svn.example.com/repos/trunk
$ svn commit -m "Исправлено исключение нулевого указателя (lol jk)"
Забавные трюки SVN:
- Версионированные каталоги (наконец-то отслеживание перемещений!).
- Более чистое слияние (всё ещё требовался доктор наук по разрешению конфликтов).
- Поддержка HTTP (WebDAV был REST API до того, как это стало круто). Но у SVN был экзистенциальный кризис — он был централизован, как CVS, в мире, жаждущем распределённых систем. Отправка в репозиторий была похожа на отправку открытки богам мейнфреймов.
Git: Распределённый повелитель времени
Затем в 2005 году Линус Торвальдс создал Git, якобы между завтраком и обедом. Git рассматривал каждый клон как полноценный репозиторий — словно давая каждому разработчику TARDIS. Современное волшебство Git:
# Инициализация репозитория
$ git init
$ git add .
$ git commit -m "Начальная фиксация (пожалуйста, не нарушайте)"
# Создать ветку функций
$ git checkout -b feature/rewrite-everything
# Путешествия во времени стали проще
$ git reflog # "О верно, вот где я оставил свою вменяемость"
Убойные функции Git:
- Всё распределено (код, история, обвинения).
- Молниеносные операции (слияние быстрее, чем у белки с кофеином).
- Простое ветвление (git-flow, GitHub Flow, 42-часовая пятничная работа). Совет: хотите почувствовать себя старым? Первый коммит Git (b9652005) теперь достаточно взрослый, чтобы пить алкоголь в США.
Практическая эволюция: от RCS до Git за 4 шага
Давайте совершим путешествие во времени с помощью практических примеров: 1. Блокировка в стиле RCS в Git (на самом деле этого делать не стоит)
# Заблокировать config.ini, как в 1985 году
$ git update-index --assume-unchanged config.ini
2. Центральный рабочий процесс в стиле CVS
# Единое центральное хранилище, все разработчики отправляют изменения в основной
$ git config --global pull.rebase true
$ git push origin main
3. Контроль версий каталогов в стиле SVN
# Отслеживать пустые каталоги с помощью .gitkeep
$ mkdir -p logs && touch logs/.gitkeep
4. Современные мощные приемы работы с Git
# Интерактивное перебазирование (редактирование истории)
$ git rebase -i HEAD~3
# Поиск ошибок bisect to find
$ git bisect start
$ git bisect bad
$ git bisect good v1.0
Почему эта история важна сегодня
Понимание эволюции систем контроля версий помогает устранять современные проблемы:
- Синтаксис
.gitignore
? Произошёл от файловignore
в RCS. - Стадии изменений Git? Духовный преемник CVS «обновление перед фиксацией».
- Конфликты слияния всё ещё неприятны, но теперь у нас есть лучшие инструменты для поиска виноватых.
В следующий раз, когда будете выполнять
git push
, помните: где-то файл RCS плачет от радости. Мы перешли от управления версиями отдельных файлов к волшебному синхронному обновлению кодовых баз планетарного масштаба. Неплохо для нескольких десятилетий работы. А теперь извините меня, мне нужно зафиксировать эту статью, прежде чем мой редактор отправит поисковую группу.