EN · RU

Документация

Полный справочник по использованию 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. Приоритет, сверху вниз:

  1. установлена NO_COLOR (любое значение, даже пустое) — цвет выключен (no-color.org);
  2. output.color: false в конфиге (или GITL_OUTPUT_COLOR=false) — цвет выключен;
  3. stdout не TTY — цвет выключен;
  4. иначе — цвет включён.

Тихий режим (output.quiet)

Без API-ключа review печатает в stderr информационное уведомление «using deterministic offline review» при каждом запуске (а changelog --ai — аналогичное уведомление об откате). Подавить его можно любым из способов:

  1. флаг --quiet у review / changelog;
  2. переменная окружения GITL_QUIET (любое значение, даже пустое);
  3. 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).

История локальна для машины — она не переживает CI-раннеры, поэтому тренд — фича для локальной работы разработчика, не для CI.
policy:
  risk_log_enabled: false   # отключение (только конфиг, CLI-флага нет)

Кастомные шаблоны

Три независимых override'а, все только через конфиг (CLI-флагов нет):

prompt:
  system_template_file: "./review-policy.md"             # путь относительно CWD
  changelog_system_template_file: "./changelog-policy.md"
output:
  template_file: "./review-output.tmpl"
Про доверие: эти ключи можно задать через repo-level .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 при высоком риске

Главное:

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'а:

{
  "mcpServers": {
    "gitl": {
      "command": "gitl",
      "args": ["mcp"]
    }
  }
}

Конфиг загружается один раз при старте так же, как у обычных команд. Без ключа tool-вызовы идут в том же детерминированном офлайн-режиме, что и CLI. stdout зарезервирован под MCP-протокол; предупреждения идут в stderr.