Правила репозитория (.gitcito.json)
В каждом проекте есть правила, которые из кода не выводятся. Никогда не
пушить напрямую в release/*. Области коммитов — api, web и infra, и
больше никаких. Нужен Node 20, выгруженные подмодули и .env, скопированный из
.env.example, иначе ничего не запустится. Такие правила живут в README,
который никто не перечитывает, в упавшей сборке CI или в голове того, кто здесь
дольше всех.
.gitcito.json — место, где репозиторий их записывает, чтобы инструмент мог на
них опираться. Файл лежит в корне репозитория, версионируется как любой другой и
потому путешествует вместе с клоном: все, кто открывает проект, получают одни и
те же правила, а новый человек получает их в первый день, а не при первом
отклонённом push.
Файл полностью необязателен. Репозиторий без него ведёт себя ровно так же, как раньше.
Писать его вручную не обязательно: чату репозитория передают схему этого файла, поэтому добавь ссылки на задачи вида JIRA-1234 или защити release-ветки возвращается как файловое действие, которое можно просмотреть.

Где его править
Шестерёнка рядом с инструментами панели → Config. Этот редактор пишет файл в рабочее дерево; больше он нигде не хранится, поэтому сделайте коммит, чтобы поделиться правилами с командой.
Если файла ещё нет, Прочитать репозиторий предложит его на основе того, что
уже есть: .nvmrc или engines.node, .gitmodules, filter=lfs в
.gitattributes, .env.example без соседнего .env, ветки, которые вы уже
защищаете локально, и области из последних 500 заголовков коммитов. Ничего не
пишется, пока вы не сохраните. В терминале то же самое делает
gitcito config init (см. командную строку).
Что может быть в файле
{
"version": 1,
"protect": ["main", "release/*"],
"links": {
"tickets": [
{ "match": "\\b[A-Z][A-Z0-9]+-\\d+\\b", "url": "https://tracker.example.com/browse/$0", "label": "Jira" }
]
},
"commit": {
"scopes": ["api", "web", "infra"],
"ticketFromBranch": true,
"trailers": ["Refs: {ticket}"]
},
"requires": {
"node": ">=20",
"hooksPath": ".husky",
"submodules": true,
"lfs": true,
"files": [{ "path": ".env", "from": ".env.example", "why": "Базовый адрес API и токен для разработки" }]
},
"checklist": {
"push": ["Прогнать интеграционные тесты на staging"]
}
}
| Поле | Что делает |
|---|---|
version |
Должно быть 1. Файл более новой схемы игнорируется целиком, а не угадывается. |
protect |
Имена веток, * совпадает с любой последовательностью символов. Добавляются к веткам, которые вы защищаете локально — см. защищённые ветки. |
links.tickets |
Регулярное выражение и шаблон адреса. $0 — всё совпадение, $1…$9 — его группы. Совпадения в заголовках и телах коммитов становятся ссылками. |
commit.scopes |
Области, которые предлагает композитор вместо свободного поля. Их объявление также превращает неизвестную область в gitcito commit-check из стилевого совета в ошибку. |
commit.ticketFromBranch |
Подставляет ключ тикета из имени ветки (feature/ABC-123-thing → ABC-123) — но только в пустой композитор, никогда поверх того, что вы печатаете. |
commit.trailers |
Строки, дописываемые в тело коммита. {ticket} и {branch} подставляются; строка, чей плейсхолдер нечем заполнить, отбрасывается, а не пишется наполовину. |
requires.* |
Что нужно работающему клону. Каждая запись становится строкой доктора, ниже. |
checklist.push |
Свободный текст, показываемый один раз за сессию перед первым push. |
Доктор
requires — та часть, которая отвечает на «я склонировал, и оно не
запускается». Gitcito проверяет её при открытии репозитория и показывает чип со
стетоскопом в строке состояния, когда что-то не так. Клик открывает вкладку
Config на строках доктора; Проверить снова запускает их заново.
| Проверка | Проходит, когда | Чинится |
|---|---|---|
node |
node в вашем PATH удовлетворяет спецификации |
— |
submodules |
Ни один подмодуль не остался без checkout | git submodule update --init --recursive |
lfs |
git-lfs установлен, а отслеживаемые файлы — настоящее содержимое, а не текст указателя | git lfs pull |
hooksPath |
core.hooksPath совпадает с объявленным путём |
установкой core.hooksPath |
files |
Файл существует | копированием из from, если он есть |
Два намеренных ограничения. Предупреждение никогда не значит «сломано» — оно
значит, что доктор не смог что-то определить (нечитаемая спецификация Node
проходит, вместо того чтобы выдумывать ошибку, с которой вы ничего не сделаете),
и предупреждения не роняют gitcito doctor в CI. И починка никогда не приходит
из файла: набор выше — это весь набор, закрытый на этапе компиляции.
Конфигурация передаёт ему значение — путь для копирования, значение для
core.hooksPath — и никогда команду.
Копирование никогда не перезаписывает: отсутствие файла — ровно та причина, по которой эта строка здесь.
Коммиты
Когда объявлены commit.scopes, кнопка области в композиторе предлагает этот
список вместо свободного поля — разница между feat(renderer) и
feat(rendererr). ticketFromBranch и trailers заполняют механические части
сообщения, а links.tickets возвращает ключам вид ссылок везде, где показан
коммит.
Те же правила действуют и вне окна: gitcito commit-check читает этот файл,
поэтому хук commit-msg и CI требуют ровно то, что предлагает композитор. См.
командную строку и коммиты.
Список перед push
checklist.push показывается как подтверждение перед первым push в сессии, по
строке на пункт. Это место для того, что действительно требует суждения — кто-
нибудь предупредил поддержку? — потому что Gitcito никогда не проверяет это за
вас. Это напоминания, а не запреты: прочитали и запушили либо отменили.
Показывается один раз на репозиторий за сессию, потому что диалог при каждом
push — это диалог, который никто не читает.
Почему он не может вам навредить
Файл приходит вместе с репозиторием, то есть от того, кто репозиторий написал. Он считается недоверенным содержимым, как и сообщение коммита:
- Ничего в нём не выполняется. Нет поля, хранящего команду, а починки доктора — фиксированный список.
- Он может только добавлять ограничения.
protectобъединяется с вашим локальным списком: репозиторий может защитить больше, чем выбрали вы, но никогда не отговорит вас что-то защищать. Ни одно поле не выключает защиту. - Пути не могут выйти за репозиторий. Абсолютные пути,
..,~, буквы дисков и всё, что касается.git, отклоняются — и проверяются ещё раз там, где строка становится настоящим путём. - Ссылки должны быть
http(s). Ничего другого системному открывателю адресов не передаётся. - У всего есть предел — длина списков, строк, шаблонов, — чтобы враждебный репозиторий не вставил стену текста в диалог и тысячу чипов в панель.
Плохое поле отбрасывается, а не рушит всё. Остальная часть файла продолжает
действовать, а отброшенное перечислено под заголовком Проигнорировано
Gitcito во вкладке Config вместе с причиной. Единственное исключение —
невалидный JSON или неизвестная version: там спасать нечего.
Чего он намеренно не делает
- Ни команд, ни скриптов, ни хуков. Для этого есть хуки, и это решение, которое вы принимаете для каждого клона.
- Ни правил на ветку, ни на человека. Один файл, один набор правил.
- Он не заменяет CI. Список — это текст; доктор проверяет окружение, а не вашу работу.
- Он ничего не может ослабить. Все защиты Gitcito остаются вашими.
См. также: Настройки репозитория · Командная строка · Коммиты · Хуки и .gitignore