Зеркало в GitHub/GitLab
Push-копия списка на внешней фордже: настройка, токены, что уезжает и как читать ошибки.
Список можно зеркалить в репозиторий на GitHub, GitLab или любой другой фордже, которая понимает git по HTTPS. SetFork остаётся источником истины, зеркало — витрина и резервная копия: после каждой новой версии SetFork сам пушит изменения наружу.
Зеркало одностороннее. Правки, сделанные прямо на фордже, обратно не приезжают и будут перезаписаны следующим пушем. Хотите править из терминала — пушьте в сам SetFork.
Что уезжает на зеркало
| Уезжает | Не уезжает |
|---|---|
Ветка main со всей историей версий | Ветки предложений (черновики) |
Теги версий v1, v2, … и теги релизов | Предложения, обсуждения, ревью |
README.md — витрина списка | Звёзды, наблюдатели, прогоны |
list.json — канон списка | Настройки списка и права доступа |
.gitattributes |
Как и при зеркалировании между самими GitHub и GitLab, переносятся только git-объекты: коммиты, ветки и теги. Всё, что живёт вокруг репозитория, остаётся в SetFork.
Шаг 1. Создайте пустой репозиторий на фордже
GitHub — New repository, без README, .gitignore и лицензии.
GitLab — New project → Create blank project, снимите галочку Initialize repository with a README.
⚠️ Не создавайте репозиторий с README. Первый пуш зеркала перезаписывает чужую
историю принудительно; на GitHub это пройдёт, а на GitLab ветка main защищена по
умолчанию и force push в неё запрещён — первый пуш упадёт.
Приватный список зеркальте в приватный репозиторий: SetFork не проверяет видимость на стороне форджи.
Шаг 2. Получите токен
Логин вводить не нужно нигде: SetFork подставляет его сам по имени хоста
(x-access-token для GitHub, oauth2 для GitLab, git для остальных).
GitHub
Fine-grained токен — Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token:
- Repository access → Only select repositories → выберите репозиторий зеркала;
- Permissions → Repository permissions → Contents → Read and write;
- срок жизни — на ваше усмотрение; после истечения зеркало перестанет пушить и напишет ошибку в настройках.
Классический токен тоже подойдёт — ему нужна область repo.
GitLab
Проект → Settings → Access tokens → Add new token:
- Role —
Maintainer: веткаmainзащищена по умолчанию, а пушить в защищённую ветку могут только Maintainer и Owner; - Scopes —
write_repository(доступ к git по HTTPS на чтение и запись).
Подойдёт и deploy token с областью write_repository.
Другие форджи
Gitea, Codeberg, Forgejo, Bitbucket: любой токен с правом записи в репозиторий.
Работает всё, что принимает https://пользователь:токен@хост/путь.git.
Шаг 3. Включите зеркало в SetFork
Откройте список → Настройки → Зеркало и заполните:
- URL репозитория —
https://github.com/вы/ваш-репозиторий(можно с.gitна конце). Толькоhttps://, без логина и токена в самом адресе; - Токен доступа — из шага 2. Он шифруется и больше не показывается. При следующем сохранении пустое поле означает «оставить прежний».
По кнопке Сохранить первый пуш уходит сразу, и рядом появляется статус: время последней синхронизации либо текст ошибки целиком.
Дальше SetFork пушит сам — после каждого события, которое двигает main:
- публикация новой версии в интерфейсе;
git pushв список;- слияние предложения, в том числе с ручным разрешением конфликтов;
- создание тега релиза.
Кнопка Синхронизировать толкает пуш вручную — ею же повторяют неудавшийся. Автоматических повторов нет: после ошибки следующая попытка будет при следующей версии или по этой кнопке.
Кнопка Отключить зеркало стирает URL и токен. Репозиторий на фордже остаётся нетронутым.
Как зеркало догоняет истину
Пуш идёт явным набором ссылок:
git push --prune <удалённый> \
+refs/heads/main:refs/heads/main \
+refs/tags/*:refs/tags/*Отсюда три следствия:
+(force) — зеркало обязано совпадать с SetFork. Ручные коммиты вmainна фордже будут потеряны при следующем пуше.--prune— тег, снятый в SetFork, исчезает и на зеркале. Посторонние ветки на фордже не трогаются: под правило попадает толькоmain.- Никакого
--mirror: он гонит вообще всё подrefs/, аrefs/pull/*у GitHub доступны только на чтение — такой пуш падал бы частично.
Ошибки и что они значат
Текст ошибки от git показывается в настройках целиком, с вырезанными учётными данными.
| Ошибка | Причина |
|---|---|
src refspec refs/heads/main does not match any | У списка ещё нет ни одной версии — публиковать нечего |
Write access to repository not granted (403) | У токена нет Contents: Read and write или он не выбрал этот репозиторий |
Invalid username or token / HTTP Basic: Access denied | Токен просрочен, отозван или скопирован не полностью |
Repository not found | Опечатка в URL либо приватный репозиторий, к которому у токена нет доступа |
pre-receive hook declined (GitLab) | Роль токена ниже Maintainer, либо в репозитории уже была история и нужен force push в защищённую ветку |
таймаут 60с (сеть/форджа не отвечает) | Форджа недоступна с сервера; нажмите «Синхронизировать» позже |
SETFORK_MIRROR_SECRET не задан на сервере | Только на своей установке — см. ниже |
Своя установка
Зеркалу нужен общий секрет шифрования токенов — переменная SETFORK_MIRROR_SECRET,
одинаковая у приложения и у git-ядра: приложение шифрует токен, ядро
расшифровывает его при пуше. Без переменной раздел работает, но каждый пуш честно
пишет ошибку в статус. Секрет — случайная строка, менять её означает сделать все
сохранённые токены нечитаемыми (их придётся ввести заново).
Серверу также нужен исходящий доступ к фордже по HTTPS.