Контроль версий нужен не только программистам. Написание книг, образовательных курсов, отчётов и статей, совместная работа над документами, всё это порождает многочисленные папки и документы вида Диплом, Диплом2, Диплом (3), Диплом (нов), Диплом-испр янв, Диплом++ и т. п.
Для наведения порядка или совместной работы над проектами я долгое время пользовался системой git, которая на сегодняшний день стала де-факто стандартной и самой распространённой системой контроля версий. Мой первый репозиторий на GitHub датируется 2012 годом, однако, в течение всех этих лет, вместе с навыком и опытом использования git, накапливалась усталость и некоторое раздражение от неё. И дело тут не в самой системе, как таковой, а в том, что мне никак не удавалось уяснить основные принципы её работы. Всë-таки, ацикличный направленный граф (дерево-фикус) достаточно нетривиальная структура.
Стоило сделать сколь-нибудь долгий перерыв в работе, и приходилось буквально заново учиться, лезть в мануалы и вспоминать, чем стейджинг отличается от коммита и в чем состоит разница между git add --amend, git reset и git restore. Работа с виртуальными ветками для экспериментов быстро превращала мой репозиторий в какую-то железнодорожную сортировочную станцию, а слияние с конфликтами редко удавалось разрулить без применения грубой силы. В общем, стало ясно, что не дорос я до git, и для решаемых мной задач вполне хватило бы менее профессиональной и универсальной системы, но с более простой и стройной внутренней логикой.
Ещё много картинок, показывающих что я не один такой — здесь.
Конечно же, git далеко не единственная система контроля версий. У неё есть с десяток альтернатив разной степени навороченности, надо было как-то выбрать наиболее подходящую. Я стал искать не самую популярную или самую крутую, а самую понятную мне систему управления версиями. В качестве основного критерия для выбора была прозрачность концепции.
Идеальная, для меня система нашлась в знакомом и близком мне мире математики и computer science. Она имеет в основе достаточно развитую теорию (patch theory), в которой изменения в файлах и папках, называемые патчами, («заплатками»), образуют полноценную алгебру, гарантирующую, там где это теоретически возможно, детерминистичность и идентичность версий, расположенных в разных удалённых репозиториях. Речь идëт о системе распределённого контроля версий Darcs, написанной на Haskell, активно развивающейся и предлагающей свой сетевой репозиторий hub.darcs.net.
Darcs предоставляет все основные базовые функции: отслеживание изменений в проекте, возможности откатить состояние на произвольное число шагов, организацию безопасного экспериментирования с вариантами кода или текста через клонирование и слияние репозиториев, а также интеграцию с Emacs, в котором я, собственно, и работаю.
И вот, спустя месяц непрерывной работы над библиотекой геометрической алгебры для hackage, я готов поделиться впечатлениями от использования Darcs.
На освоение команд Darcs и просмотр ролика на YouTube у меня ушло часа два. После чего работа пошла гладко. Настройка соединения с сервером удалённого репозитория через SSH, после мучений с современной системой аутентификации GitHub, вызвала только тёплую благодарность за простоту и понятность. Конечно, пригодился опыт работы с git, но надо отдать должное, документация и интерактивное взаимодействие с пользователем у Darcs на высоте.
К тому же система не перегружена функциями (в git 130 команд, в Darcs — 20), но те, что у неё есть, она выполняет хорошо.
Вместо деревьев и снимков, эта система стремится создавать линейные цепочки изменений, патчей. Линейность и математическая основа приводит к тому, что изменения репозитория с операциями слияния обладают рядом хороших свойств: обратимостью, коммутативностью и ассоциативностью, что делает слияния предсказуемыми и позволяет уменьшить как размер индекса изменений, так и количество потенциальных конфликтов.
И, да, знать о существовании гомологической теории патчей для использования Darcs не нужно, так же, как незнание матриц или кватернионов не мешает резаться в 3D шутер.
К сожалению, полностью избежать конфликтов при слиянии изменений невозможно даже теоретически. Это связано с тем, что коммутируют, всё-таки, не все изменения и не всякий направленный ацикличный граф можно вытянуть в цепочку без потери информации. Среди патчей существуют контекстно-зависимые пары обратимых, но не коммутирующих элементов. Простейший пример: создание файла и внесение в него изменений нельзя поменять местами. Однако такие типы патчей легко распознаются и система, в случае конфликта, достаточно внятно объясняет что произошло. Вообще, Darcs по умолчанию весьма говорлива.
За десять лет существования и развития Darcs разработчикам удалось преодолеть ряд математических сложностей, к которым приводит прямое использование алгебры патчей. В частности, «комбинаторные взрывы», которые наблюдались в первых версиях, приводили к зависанию системы. Введение и последовательное расширение типизации патчей, а также вывод упрощающих формул, с этой проблемой успешно справились.
К недостаткам можно отнести то, что в Darcs нет виртуальных веток (branches в git). Надо сказать, в сообществе разработчиков до сих пор нет единого мнения, нужны ли они вообще. Для введения новых экспериментальных изменений, для которых чаще всего и используются ветки, Darcs cоздаëт клон репозитория в отдельной директории. После тестирования, этот клон сливается с тем репозиторием, который считается стабильным или готовым к релизу, после чего удаляется, либо остаëтся для истории, если идея не пошла дальше эксперимента. Таким образом, ветки не заполняют собой индекс основного репозитория, оставляя его максимально чистым.
После развитой системы виртуальных веток в git, такой подход сначала кажется примитивным. Но после месяца работы и пары сотен коммитов в шести экспериментальных ветках, я всецело его принял. Во-первых, он надёжен и прост как пробка и запутаться в реальных, а не виртуальных ветках практически невозможно. Во-вторых, все "живые" ветки явно видны в локальном репозитории и доступны одновременно, без необходимости в графическом интерфейсе. А в-третьих, удаление ненужной ветки тривиально, безболезненно и не требует никаких операции типа git rebase, в силу детерминистичности слияний. При необходимости, любой из клонов можно сохранить на сервере darcs hub и не бояться потерять локально.
В общем, после дюжины лет возни с git, как с профессиональным фотоаппаратом, я с облегчением разрешил себе просто "снимать на телефон", осознав, что я не работаю в крупной корпорации и не собираюсь писать ядро Linux.
Наконец, мне приятно видеть в действии красивую математическую теорию и любимый язык программирования. Кроме Darcs идеи теории патчей реализованы в системе контроля версий Pijul, написанной на Rust.