Документация
Полный справочник по использованию gitl v0.6.2.
Нужен git в PATH; Go 1.22+ — только для
go install / сборки из исходников.
Установка
# Homebrew (macOS/Linux)
brew install akomyagin/tap/gitl
# npm — скачивает готовый бинарник под вашу платформу из GitHub Releases
# и проверяет его SHA256-сумму (Go-тулчейн не нужен)
npx gitl-cli review HEAD~5..HEAD # или: npm install -g gitl-cli
# Go-тулчейн
go install github.com/akomyagin/gitl/cmd/gitl@latest
Либо скачайте подписанный бинарник из GitHub Releases — каждый релиз подписан cosign (keyless) и покрыт SLSA L3 provenance; шаги проверки — в VERIFY.md.
Команды и флаги
# AI-ревью диапазона коммитов — токены стримятся в терминал
GITL_API_KEY=sk-... gitl review HEAD~5..HEAD
# без ключа — детерминированное офлайн-ревью (эвристический риск, без сети)
gitl review HEAD~5..HEAD
# ревью staged (ещё не закоммиченных) изменений перед `git commit`
gitl review --staged
# ревью GitHub PR по номеру — нужен `gh` CLI (установлен + залогинен);
# base/head резолвятся через gh, при необходимости делается локальный fetch
# `pull/N/head`, ревьюится diff от merge-base (base...head) — как показывает GitHub
gitl review pr/42
# машиночитаемый вывод для CI + гейтинг по риску
gitl review HEAD~5..HEAD --format=json
gitl review HEAD~5..HEAD --fail-on=high # exit-код 2 при высоком риске
# оценка стоимости без реального вызова API
gitl review HEAD~5..HEAD --dry-run
# ограничить оценочную стоимость прогона
gitl review HEAD~5..HEAD --max-cost-usd=0.50
# пропустить дисковый кэш ответов (всегда вызывать модель)
gitl review HEAD~5..HEAD --no-cache
# отключить стриминг (буферизованный вывод)
gitl review HEAD~5..HEAD --no-stream
# подавить информационное офлайн-уведомление на stderr
# (также через GITL_QUIET=1 или output.quiet: true)
gitl review HEAD~5..HEAD --quiet
# changelog с последнего тега (или вся история, если тегов нет) — без LLM
gitl changelog
gitl changelog v1.2.0..HEAD --format=json
# AI-changelog: модель переписывает результат в прозу release notes; без ключа —
# откат к детерминированному changelog, команда никогда не падает
GITL_API_KEY=sk-... gitl changelog --ai
# сводка активности за последние N дней — без LLM
gitl digest --days=14
# мульти-репо digest: параллельно; недоступный репозиторий не валит остальные
gitl digest --repos=../service-a,../service-b --format=json
# интерактивный TUI-просмотрщик (нужен TTY)
gitl digest --days=14 --tui
# записать прокомментированный стартовый .gitl.yaml в корень репозитория
gitl init
gitl version
gitl --help
Все три команды поддерживают --format=md|text|json. Кастомный
системный промпт ревью задаётся только через конфиг
(prompt.system_template_file); флага
--system-template нет — см.
Кастомные шаблоны.
Exit-коды
| Код | Значение |
|---|---|
0 | ок — риск ниже порога --fail-on (или гейт не задан) |
1 | ошибка инструмента — git, LLM или конфиг |
2 | сработал риск-гейт --fail-on — CI может ветвиться именно по 2 |
Автодополнение
gitl поставляет cobra-сгенерированные скрипты автодополнения для bash, zsh,
fish и PowerShell. Homebrew устанавливает bash/zsh/fish автоматически (релизные
архивы тоже содержат скрипты в completions/). Иначе:
# bash (текущая сессия)
source <(gitl completion bash)
# bash (постоянно) — Linux
gitl completion bash > /etc/bash_completion.d/gitl
# zsh (постоянно)
gitl completion zsh > "${fpath[1]}/_gitl"
# fish
gitl completion fish > ~/.config/fish/completions/gitl.fish
# PowerShell
gitl completion powershell | Out-String | Invoke-Expression
Флаги с фиксированным набором значений — --format (md|text|json),
--fail-on (never|low|medium|high) и --provider —
дополняются до допустимых значений.
Конфигурация
Быстрый путь: gitl init записывает прокомментированный стартовый
.gitl.yaml в корень репозитория (существующий файл не перезаписывает
без --force; --output пишет в другое место).
Два уровня, сливаются по приоритету:
флаг > env > .gitl.yaml (репо) >
~/.config/gitl/config.yaml (личный).
Repo-level .gitl.yaml коммитится как общая политика команды (порог
риска, исключённые пути, категории changelog). Без ключа gitl работает в
детерминированном офлайн-режиме.
В офлайн-режиме — а также когда реальная модель не вернула валидный
risk-блок и gitl откатился к эвристике — risk-шапка помечается суффиксом
*(heuristic)* (и "heuristic": true в
--format=json): детерминированную оценку нельзя принять за
собственное суждение модели.
Провайдеры (llm.provider)
# OpenAI-совместимый API (дефолт)
llm:
provider: "openai"
api_key: "" # или env GITL_API_KEY
base_url: "https://api.openai.com/v1"
model: "gpt-4o-mini"
# Ollama — локально/self-hosted, без ключа, бесплатно
llm:
provider: "ollama"
base_url: "http://localhost:11434/v1"
model: "llama3.1"
# Azure OpenAI — свой формат auth/endpoint
llm:
provider: "azure_openai"
api_key: "" # или env GITL_API_KEY
model: "gpt-4o-mini" # используется только для оценки стоимости
azure_openai:
endpoint: "https://<resource>.openai.azure.com"
deployment: "<deployment-name>"
api_version: "2024-08-01-preview"
# Anthropic (нативный Claude Messages API)
llm:
provider: "anthropic"
api_key: "" # или env GITL_API_KEY
model: "claude-sonnet-4-6"
# base_url необязателен; по умолчанию https://api.anthropic.com
# Google Gemini (Google AI Studio)
llm:
provider: "gemini"
api_key: "" # или env GITL_API_KEY
model: "gemini-2.5-flash"
# base_url необязателен; по умолчанию https://generativelanguage.googleapis.com/v1beta
Стриминг (output.stream)
При интерактивном ревью (md или text в TTY) gitl
стримит токены в терминал по мере поступления. Стриминг включён по умолчанию и
автоматически отключается в CI (не-TTY stdout), с --format=json, а
также при заданном кастомном output.template_file (шаблону нужен
полный ответ, поэтому ревью буферизуется и рендерится через него).
Стриминг сейчас реализован только для OpenAI-совместимого
провайдера (openai / ollama /
azure_openai). С нативным anthropic или
gemini gitl прозрачно отдаёт то же ревью одним буферизованным
ответом, независимо от output.stream / --no-stream.
output:
stream: true # по умолчанию; false — всегда буферизовать
Цвет (output.color)
В интерактивном терминале gitl review подсвечивает уровень
риска в заголовке (HIGH — красный, MEDIUM — жёлтый, LOW — зелёный). Цвет
автоматически отключается, когда stdout не TTY, и никогда не попадает в
--format=json. Приоритет, сверху вниз:
- установлена
NO_COLOR(любое значение, даже пустое) — цвет выключен (no-color.org); output.color: falseв конфиге (илиGITL_OUTPUT_COLOR=false) — цвет выключен;- stdout не TTY — цвет выключен;
- иначе — цвет включён.
Тихий режим (output.quiet)
Без API-ключа review печатает в stderr информационное
уведомление «using deterministic offline review» при каждом запуске (а
changelog --ai — аналогичное уведомление об откате). Подавить его
можно любым из способов:
- флаг
--quietуreview/changelog; - переменная окружения
GITL_QUIET(любое значение, даже пустое); output.quiet: trueв конфиге (илиGITL_OUTPUT_QUIET=true).
--quiet глушит только информационный баннер: ошибки, само
ревью/changelog на stdout и гейт --fail-on не затрагиваются.
Кэш LLM-ответов (cache)
gitl review кэширует ответы модели на диск (SHA-256 от
провайдера + модели + промпта) в ~/.cache/gitl/review/
(XDG-совместимо). Одинаковые диффы переиспользуют кэш мгновенно — без
API-вызова и затрат.
cache:
enabled: true # по умолчанию
ttl_hours: 24 # записи старше игнорируются
Пропустить для одного вызова — --no-cache. В
--format=json каждый артефакт несёт аддитивные метаданные прогона:
duration_ms (wall-clock прогона) и
cache: { "hit": bool, "tier": "none|local|tiered" } —
tier сообщает сконфигурированную топологию кэша, а не бэкенд
конкретного попадания.
Общий remote-кэш (cache.remote) — opt-in
Выключен по умолчанию, BYO-backend: gitl не хостит сервис и не делает ни одного сетевого запроса ни к какому кэшу, пока вы его не сконфигурируете. Полезен для холодных стартов CI — общий HTTP KV endpoint позволяет одному runner'у переиспользовать ревью того же диффа, сделанное другим.
cache:
enabled: true
ttl_hours: 24
remote: # opt-in общий кэш для холодных стартов CI
url: https://cache.example.com/gitl # ваш endpoint; gitl ничего не хостит
token_env: GITL_REMOTE_CACHE_TOKEN # env-переменная с опциональным bearer-токеном
timeout_ms: 3000
Локальный дисковый кэш остаётся первым уровнем: чтение проверяет диск, затем
remote (remote-хит дозаписывается на диск); запись идёт в оба. Протокол — тупое
key-value хранилище поверх HTTP: GET {url}/{key} → 200 с
JSON-записью или 404 = промах; PUT {url}/{key} с JSON-записью →
любой 2xx = сохранено. Если token_env называет env-переменную с
непустым значением, оба запроса несут Authorization: Bearer. Ключи
— 64-символьные hex-строки SHA-256.
Контракт безопасности: любая ошибка remote молча деградирует к локальному кэшу — ревью никогда не падает из-за него. В записях только ответ модели под непрозрачным хэшом: ни дифф, ни текст промпта в remote-кэш не попадают.
Тренд риска (policy.risk_log_enabled)
Каждый запуск gitl review дописывает свой risk-результат в
локальный JSONL-лог (~/.local/share/gitl/risk-history.jsonl;
%AppData%\gitl\ на Windows). gitl digest читает его и
показывает per-repo секцию «Risk trend (last N days)» — число ревью по уровням,
направление high-risk и несколько последних ревью. В --format=json
это опциональное поле risk_trend. Ревью коррелируются с
репозиторием по URL remote origin (fallback — путь worktree).
policy:
risk_log_enabled: false # отключение (только конфиг, CLI-флага нет)
Кастомные шаблоны
Три независимых override'а, все только через конфиг (CLI-флагов нет):
prompt.system_template_file— собственный системный промпт ревью (чеклист безопасности, архитектурные ограничения, правила команды). Используется толькоgitl review; шаблону доступны{{ .Commits }},{{ .Diff }},{{ .Range }},{{ .Staged }}.prompt.changelog_system_template_file— собственный системный промпт changelog'а, используется толькоgitl changelog --ai; ему доступны{{ .Commits }},{{ .Range }},{{ .Grouped }}— но не{{ .Diff }}(changelog --aiработает по метаданным коммитов, диффа там нет).output.template_file— собственный шаблон рендераmd-формата для готового артефакта ревью.
prompt:
system_template_file: "./review-policy.md" # путь относительно CWD
changelog_system_template_file: "./changelog-policy.md"
output:
template_file: "./review-output.tmpl"
.gitl.yaml, значит gitl review на
склонированном недоверенном репозитории может указать на шаблон внутри этого же
репозитория. text/template здесь не читает произвольные файлы и не
исполняет код, но к .gitl.yaml недоверенного репозитория стоит
относиться с той же осторожностью, что и к его .git/hooks или
build-скриптам.CI-интеграции
GitHub Action
Action AI-ревьюит коммиты пул-реквеста и оставляет sticky-комментарий с
риск-скором, опционально блокируя merge по порогу. Собирает gitl из исходников
(go install на пиннутой версии).
name: gitl review
on:
pull_request:
permissions:
contents: read # для checkout
pull-requests: write # чтобы оставить комментарий-ревью
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0 # обязательно: без полной истории base..head не резолвится
- uses: akomyagin/gitl@v0.6.2
with:
gitl-api-key: ${{ secrets.GITL_API_KEY }} # BYOK
fail-on: high # опционально: блокировать merge при высоком риске
Главное:
- Ключ — только через
secrets.*. Если секрет не задан, Action работает в детерминированном офлайн-режиме (без сети и затрат). - Минимальные permissions. Нужны только
pull-requests: writeиcontents: read. fetch-depth: 0обязателен — shallow-клон не разрешитbase.sha..head.sha.fail-onпо умолчаниюnever— Action только комментирует, пока вы явно не включите гейт. Когда гейт срабатывает, job падает с exit-кодом2; настоящая ошибка инструмента даёт1.- Выбор провайдера. Передайте
provider:(openai|ollama|azure_openai|anthropic|gemini), опциональноmodel:иbase-url:, рядом сgitl-api-key:. Если опустить — значения берутся из.gitl.yaml/личного конфига и дефолтов gitl. - Приватность диффов. В CI дифф уходит настроенному LLM-провайдеру. Для закрытого кода используйте self-hosted/enterprise-провайдер (Ollama, Azure OpenAI).
- Риск-сводка в описании PR (opt-in). С
update-pr-description: true(по умолчаниюfalse) Action дополнительно поддерживает компактный блок риск-сводки в конце описания PR, ограниченный парой маркеров — заменяется только текст между ними. Пока только GitHub.
Gitea Actions (экспериментально)
Тот же action.yml работает на Gitea Actions — платформа
определяется в рантайме по переменной GITEA_ACTIONS=true, а
sticky-комментарий постится через REST API Gitea с помощью curl
вместо gh CLI.
name: gitl review
on:
pull_request:
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: https://github.com/actions/checkout@v7
with:
fetch-depth: 0
- uses: https://github.com/akomyagin/gitl@v0.6.2
with:
gitl-api-key: ${{ secrets.GITL_API_KEY }} # BYOK; без ключа — офлайн-режим
Требования: включённые Actions, свежий act_runner (с поддержкой node24) и
образ runner'а с bash, git, curl,
jq и node. REST-путь проверен end-to-end на реальном
Gitea-инстансе; окружение act_runner в живом CI пока экспериментально —
баг-репорты с реальных инстансов очень приветствуются.
GitLab CI (экспериментально)
gitl поставляет GitLab CI/CD component, зеркалящий GitHub Action: он ревьюит диапазон merge request'а и создаёт/обновляет sticky-комментарий MR. На gitlab.com подключайте как catalog-компонент:
# .gitlab-ci.yml (gitlab.com)
include:
- component: gitlab.com/alkom68/gitl/gitl-review@v0.6.2
inputs:
fail_on: "never" # по умолчанию; "high" — блокировать рискованные MR
На self-hosted GitLab подключайте шаблон через include:remote
напрямую с GitHub:
# .gitlab-ci.yml (self-hosted GitLab)
include:
- remote: "https://raw.githubusercontent.com/akomyagin/gitl/v0.6.2/templates/gitl-review.yml"
inputs:
fail_on: "never"
Настройка — две CI/CD-переменные (обе masked, никогда в YAML):
GITL_API_KEY (опционален; без него — офлайн-ревью) и
GITL_GITLAB_TOKEN (project access token или PAT, scope
api, роль Reporter+, для постинга комментария — fallback на
CI_JOB_TOKEN обычно не имеет прав на Notes API). REST-вызовы и
YAML компонента проверены на реальном GitLab CE; живой прогон пайплайна пока
экспериментален.
Bitbucket Pipelines (экспериментально)
Интеграция с Bitbucket — это Pipe: самодостаточный Docker-образ
(alkom68/gitl-review-pipe на Docker Hub, публикуется с
v0.5.2), который резолвит диапазон PR, запускает
gitl review --format=json и создаёт/обновляет sticky-комментарий
PR.
# bitbucket-pipelines.yml
pipelines:
pull-requests:
'**':
- step:
name: gitl review
clone:
depth: full # дефолтный клон глубиной 50 может не содержать базу PR
script:
- pipe: docker://alkom68/gitl-review-pipe:0.6.2
variables:
GITL_API_KEY: $GITL_API_KEY # BYOK; уберите для офлайн-ревью
GITL_BITBUCKET_TOKEN: $GITL_BITBUCKET_TOKEN # постит комментарий PR
# FAIL_ON: "high" # по умолчанию "never" — только комментарий
Настройка — две secured-переменные репозитория/workspace:
GITL_API_KEY (опционален) и GITL_BITBUCKET_TOKEN
(access token со scope pullrequest:write; альтернатива —
GITL_BITBUCKET_USER + GITL_BITBUCKET_APP_PASSWORD для
Basic-аутентификации). Pipe не исполняет ничего, скачанного в рантайме —
бинарник и скрипты вшиты в версионированный образ. Поток внутри контейнера
проверен против мока Bitbucket API; live-пайплайн пока экспериментален.
Pre-commit-хук
gitl поставляет хук для фреймворка
pre-commit, чтобы
gitl review --staged --quiet запускался перед каждым коммитом —
локально, офлайн и бесплатно по умолчанию.
repos:
- repo: https://github.com/akomyagin/gitl
rev: v0.6.2 # пиньте на релизный тег
hooks:
- id: gitl-review
затем — pre-commit install. Фреймворк сам собирает бинарник
gitl (language: golang) и кэширует окружение: стоимость сборки
платится один раз. Opt-in блокирующего режима с лимитом стоимости:
hooks:
- id: gitl-review
args: [--fail-on=high, --max-cost-usd=0.05]
Обычный git-хук тоже работает:
# .git/hooks/pre-commit (chmod +x)
#!/usr/bin/env bash
set -euo pipefail
gitl review --staged --quiet || true
# чтобы блокировать коммит при высоком риске:
# gitl review --staged --quiet --fail-on=high
MCP-сервер
gitl mcp запускает gitl как
Model Context Protocol
stdio-сервер — для интерактивной работы с gitl внутри агентской сессии (Claude
Desktop, Cursor, Windsurf и т.д.) вместо вызова через shell. Два tool'а:
gitl_review— тот же движок, чтоgitl review:range/pr/staged(ровно один), опциональный per-call оверрайдmodel. Провайдер и endpoint фиксируются при старте сервера сознательно: tool вызывает AI-агент, которым можно управлять через prompt injection прямо в ревьюируемом контенте — per-callbase_urlпозволил бы вредоносному коммиту перенаправить запрос и слить настоящий API-ключ. Всегда возвращает структурированный JSON-артефакт;risk.levelвозвращается как данные (--fail-onв MCP-режиме нет — нет exit-кода процесса).gitl_digest— то же, чтоgitl digest:days(по умолчанию 7), опциональныйrepos. Без явногоrepostool дайджестит только рабочую директорию сервера (плюсdigest.reposиз.gitl.yaml) — никогда не обходит произвольные пути по собственной инициативе.
{
"mcpServers": {
"gitl": {
"command": "gitl",
"args": ["mcp"]
}
}
}
Конфиг загружается один раз при старте так же, как у обычных команд. Без
ключа tool-вызовы идут в том же детерминированном офлайн-режиме, что и CLI.
stdout зарезервирован под MCP-протокол; предупреждения идут в
stderr.