Поиграем в "Game of Trees"?

Опубликовано 11.09.2025 в OpenBSD

OpenBSD славится своей особой культурой разработки, где "просто" - это когда просто устроено, где достаточный минимализм и чистота кода важнее гибкости и настраиваемости, где сплошь и рядом предпочитают не приспосабливать существующие инструменты, а создавать новые с нуля.

Одним из примеров вышеупомянутого можно считать систему контроля версий (VCS) "Game of Trees"¹ ("got"), созданную с нуля разработчиками OpenBSD. Чем оно лучше/хуже, зачем оно нужно, когда уже есть Git, должно ли оно заменить Git, должно ли оно заменить CVS в OpenBSD и насколько сильно авторы нуждаются в вашем мнении о бесполезности их проекта - кратко, но ёмко описано в официальном FAQ² проекта. На первых порах очень небесполезной окажется краткая сравнительная шпаргалка по функциям Got VS Git, CVS и SVN³. И, наконец, традиционно (для проектов OpenBSD) актуальные, подробные и исчерпывающие man-страницы по всем инструментам и форматам также доступны онлайн⁴. Отдельно отмечу важное: на уровне хранения репозитория Got использует формат Git, что позволяет работать с репозиторием параллельно используя Git (например, при необходимости каких-то сложных и вычурных сценариев/настроек, которые в Got не реализованы).
¹ Game of Trees (Web site)
² Game of Trees FAQ
³ Comparison to other version control systems
⁴ Got Manual Pages

Но к чёрту сухую теорию, перейдём к практике. Как совершенно справедливо заметил Ричард "Мозолеядец" Столлман, свои данные нужно держать в своих руках, не доверяя их третьим лицам, дабы не попасть в рабство к этим самым лицам. Поэтому к чёрту американский GitHub, к черту российский GitFlic, к черту даже кошерный, казалось бы, "Game of Trees Hub"⁵, потому что у него тоже зицпредседатель ака "fiscal host" в Эуропейской юрисдикции, а значит веры им нет! Мы будем поднимать свой собственный got-репозиторий.
⁵ Game of Trees Hub

Перво-наперво, на нашем OpenBSD-сервере установим необходимый инструментарий - пакет клиентского ПО got и демон gotd (при необходимости удаленного администрирования репозитория без доступа к консоли сервера можно также поставить пакет gotsysd, а если хочется иметь лаконичный web-интерфейс, доступный снаружи, то есть пакет gotwebd, но я их не использую ибо мне не надо):

# pkg_add got gotd

затем создадим каталог для нашего репозитория, инициализируем там пустой репозиторий и предоставим права на него служебному пользователю _got (он создался в системе автоматически при установке gotd):

# mkdir -p /var/got/myrepo.got
# got init /var/got/myrepo.got/
# chown -R _gotd:_gotd /var/got

Теперь нам нужен будет пользователь с правами на работу с got-репозиторием (тот, что будет подключаться к нашему серверу удалённо, слать и/или качать изменения в репозиторий и так далее). Назовем его "myuser", это обычный пользователь unix-системы. Создадим его при помощи adduser (пароль не задаём, логиниться по паролю в шелл на нашем сервере ему не надо), а в качестве login shell ему укажем gotsh. Дело в том, что демон gotd умеет взаимодействовать только через юникс-сокет и сам в эти ваши интернеты не лазит - для подключения к нему извне по ssh и нужна прослойка в виде НЕинтерактивного шелла gotsh.

Да, поскольку подключаться извне мы будем по ssh по ключам (никаких паролей! харам!), не забываем настроить соответствующим образом /home/myuser/.ssh/authorized_keys. А в /etc/ssh/sshd_config добавим:

Match User myuser
    DisableForwarding yes
    PermitTTY no

После чего не забываем сделать "rcctl restart sshd".

Теперь создадим файл конфигурации /etc/gotd.conf (в моем примитивном случае один репозиторий доступен на чтение/запись одному пользователю, в man gotd.conf можно подсмотреть и более продвинутые примеры):

# Run gotd as the default user:
user _gotd

# Listen on the default socket:
listen on "/var/run/gotd.sock"

# Connect to repo via ssh://myuser@myhostname:port/myrepo
repository "myrepo" {
    path "/var/got/myrepo.got"
    permit rw myuser
}

проверим конфиг на корректность:

# gotd -n

если всё ОК, запустим демон:

# rcctl start gotd

проверим, что репозиторий доступен: gotctl info должен вернуть нам вывод наподобие такого

gotd PID: 98057
verbosity: 0
number of repositories: 1
number of connected clients: 0
repository "myrepo", path /var/got/myrepo.got

Собственно, серверная часть настроена. Всё совсем несложно.

Теперь проделаем пару несложных движений на клиенте (машине, где мы будем говнокодить и слать продукцию в репозиторий), в моём случае у меня уже есть локальный каталог (скажем, ~/mycode ) с начальной версией продуктов интеллектуального труда. Тут есть один любопытный нюанс: в большинстве систем контроля версий (да хоть том же git), собственно, локальный репозиторий для отслеживания изменений расположен там же, где и дерево каталогов с отслеживаемыми файлами. Но для got применяется иной подход: там репозиторий это отдельный каталог, а рабочее дерево/деревья - отдельные. Если задуматься, то так оно даже логичнее.

Итак, создадим пустой репозиторий и наполним его имеющимся контентом:

got init ~/myrepo.got
got import -r ~/myrepo.got/ ~/mycode

Больше начальный каталог ~/mycode нам, в принципе, не нужен - его можно удалить.

Далее создадим себе "рабочее дерево" ("working tree"), где и будем впредь работать.

got checkout ~/myrepo.got/ ~/myrepo

Ну и осталось только настроить связь с удаленным репозиторием: для этого создадим файл got.conf - его можно создавать как в корне репозитория ~/myrepo.got, так и в папке .got отдельных рабочих деревьев (если нужно, например, переопределить настройки основного репозитория для данного конкретного рабочего дерева). Итак, содержимое got.conf:

remote "origin" {
    server myhostname
    protocol ssh
    repository "myrepo.got"
}

Ну а дальше удобно работать прямо из рабочего дерева: добавить все новые файлы для отслеживания (добавляйте "-R" если нужно пройтись рекурсивно по каталогам, по умолчанию этого не делается):

got add -R .

закоммитить изменения:

got commit -m "комментарий"

отослать изменения в удаленный репозиторий:

got send

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

got fetch

обновить рабочее дерево до актуального состояния:

got update -b origin/main

Ну и так далее, см. man got. При желании внимательно поизучать историю коммитов, диффы и так далее - в комплекте с got идет приятный глазу консольно-псевдографический инструмент tog с довольно интуитивным (для вимеров) управлением. И опять-таки, полной и актуальной man-страницей.