--- name: project-git-setup title: "Git-инициализация нового проекта (gitverse.ru + gitea pull-mirror)" description: "Use when setting up git for a new project." version: 1.0.0 author: hermes license: MIT --- # Git-инициализация нового проекта ## When to Use Любой новый проект или перевод существующего каталога под git — сразу после создания проекта (даже «пустого», с одним README). Схема: локальный git → **приватный** репозиторий на gitverse.ru (истина) → **pull mirror** в gitea.nixg.ru (локальная резервная копия, синхронизация каждые **12 часов** = 2 раза в сутки). ## Триггеры - «новый проект», «заведи git», «инициализируй репозиторий» - Создание проекта, который будет жить в `/opt/` (стандарт окружения — всё в /opt) - **Создание/существенное обновление Hermes-скилла** — каждый самописный скилл хранится в ОТДЕЛЬНОМ приватном git-репозитории (gitverse kpa39l/ + pull mirror в gitea estorozhenko/, интервал 12h). Так скиллы переживают поломку bigbox. После создания/правки скилла — закоммитить и запушить в его репозиторий (каталог скилла уже настроен как git-worktree, remote origin указывает на gitverse; убедиться `git status` чист, `git push`). ## Шаг 0. Собрать факты - Имя репозитория: lowercase, дефисы (`tproxy-web`, `monitoring`, `openspec-lab`) - Путь проекта (обычно `/opt/`) - Стек: есть ли `Dockerfile` / `docker-compose.yml` / `compose.yaml`? Node/Python/Go? - Существующий `.gitignore` (дополнить, не затирать) ## Токены — только из настроек (НИКОГДА не искать по каталогам) Единый источник: **`/opt/hermes/.hermes/secrets/git-tokens.env`** (chmod 600). ```bash source /opt/hermes/.hermes/secrets/git-tokens.env # → GITVERSE_LOGIN, GITVERSE_PAT, GITVERSE_API, GITEA_API, GITEA_TOKEN ``` Если файла нет — создать по образцу (значения брать из obsidian `homelab/gitea.nixg.ru/Gitverse mirror token.md` ИЛИ из URL существующего mirror: `docker exec gitea cat /data/git/repositories/estorozhenko/.git/config`), затем записать в secrets и chmod 600. **Правила:** - Токены в коде/README/коммитах не хранить. В `.gitignore` всех проектов — строка `secrets/`. - Внутри скиллов и reference — только плейсхолдеры ``/${GITVERSE_PAT}, не значения. - Новый токен создаётся один раз, кладётся в secrets файл, дальше только `source`. ## Шаг 1. .gitignore Шаблон `templates/docker-gitignore.md` использовать если в проекте есть docker (compose/Dockerfile — почти всегда в наших проектах). Для не-docker проектов — базовый шаблон оттуда без docker-секции. Дополнить спецификой стека (секции Python/Node/Go в шаблоне). **НИКОГДА не игнорить**: `docker-compose*.yml`, `Dockerfile*`, `README*`, `*.md`, `*.yml` конфиги, план/статус-файлы (PLAN.md, STATUS.md, TODO.md). ## Шаг 2. Локальный git ```bash cd /opt/ git init git config user.name "estorozhenko" # если не задан глобально git config user.email "estorozhenko@nixg.ru" git add -A git commit -m "Initial commit" ``` ## Шаг 3. Создать ПРИВАТНЫЙ репозиторий на gitverse.ru ```bash source /opt/hermes/.hermes/secrets/git-tokens.env # проверить логин (реальный аккаунт — kpa39l, НЕ estorozhenko!) curl -s -H "Authorization: Bearer $GITVERSE_PAT" \ -H "Accept: application/vnd.gitverse.object+json;version=1" \ "$GITVERSE_API/user" # создать репо: private:true ОБЯЗАТЕЛЬНО, auto_init:false (иначе push упадёт) curl -s -X POST "$GITVERSE_API/user/repos" \ -H "Authorization: Bearer $GITVERSE_PAT" \ -H "Accept: application/vnd.gitverse.object+json;version=1" \ -H "Content-Type: application/json" \ -d "{\"name\":\"\",\"description\":\"<описание>\",\"private\":true,\"auto_init\":false}" ``` HTTP 201 = создан; 409 = уже существует. ## Шаг 4. Push на gitverse ```bash git remote add origin "https://$GITVERSE_LOGIN:$GITVERSE_PAT@gitverse.ru/$GITVERSE_LOGIN/.git" git push -u origin <текущая-ветка> ``` Ветку НЕ переименовывать без явной команды пользователя (в разных проектах уже master и main — сохранять как есть). ## Шаг 5. Pull mirror в gitea (синхронизация 2 раза в сутки) ```bash source /opt/hermes/.hermes/secrets/git-tokens.env # токен gitea уже в GITEA_TOKEN; при необходимости перевыпустить: # docker exec -u 1000 gitea gitea admin user generate-access-token \ # --username estorozhenko --token-name -mirror \ # --scopes "read:repository,write:repository,read:user,write:user" --raw # и обновить GITEA_TOKEN в secrets/git-tokens.env curl -X POST "$GITEA_API/repos/migrate" \ -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" \ -d "{\"clone_addr\":\"https://oauth2:$GITVERSE_PAT@gitverse.ru/$GITVERSE_LOGIN/.git\", \"repo_name\":\"\",\"repo_owner\":\"estorozhenko\",\"service\":\"git\", \"mirror\":true,\"mirror_interval\":\"12h\"}" ``` HTTP 201 = mirror создан, интервал 12h = два раза в сутки. ## Шаг 6. Проверка (обязательно) 1. HEAD совпадает: ```bash source /opt/hermes/.hermes/secrets/git-tokens.env git ls-remote "https://oauth2:$GITVERSE_PAT@gitverse.ru/$GITVERSE_LOGIN/.git" HEAD docker exec gitea git --git-dir=/data/git/repositories/estorozhenko/.git rev-parse HEAD ``` 2. Принудительная синхронизация: ```bash curl -X POST "$GITEA_API/repos/estorozhenko//mirror-sync" \ -H "Authorization: token $GITEA_TOKEN" # → 200 ``` После этого работать как обычно: `git commit` + `git push`; mirror подтянет изменения автоматически через ≤12ч. ## Питфолы (проверено на практике) - **База gitverse API — `https://api.gitverse.ru`**, НЕ `gitverse.ru/api/v1/...` (тот путь отдаёт HTML Next.js SPA, не JSON). - Gitea migrate **с ssh:// всегда 422** — только `https://oauth2:@gitverse.ru/...`. Настраивать SSH-протокол в MIGRATIONS_ALLOWED_PROTOCOLS бесполезно (известный баг, не листать заново). - `auto_init: false` — иначе gitverse создаёт свой README, и первый push падает (non-fast-forward). - `private: true` — требование пользователя, не забывать. - `mirror_interval: "12h"` = два раза в сутки; "8h" не подходит по ТЗ. - Токены не хранить в коде/README/коммитах — только в remote URL и переменных сессии. ## Связанные навыки - `git-forge-management` — общие операции с gitverse/gitea, references `gitea-pull-mirror-gitverse.md`, `gitverse-api.md` - `github-repo-management` — для GitHub (gh CLI)