gitl
gitl
面向 CLI 和 CI 的 AI 驱动的 git 历史审查工具。 gitl(git-log-lens)读取仓库的 git 历史,并通过 LLM 将其转化为结构化的工程产物:
gitl review <range>— 对提交范围 / PR 进行 AI 审查,并提供机器可读的风险评分(low|medium|high),用于 CI 门禁(--fail-on=high→ 退出码 2);实时将 token 流式输出到终端;磁盘上的 LLM 响应缓存,并可选共享远程缓存用于 CI;自定义系统提示模板;--staged在git commit之前审查暂存(未提交)的更改(也可作为 pre-commit 钩子 使用)。gitl changelog [<range>]— 生成 Keep a Changelog 风格的变更日志,按 conventional commits 分组(默认从最后一个标签到HEAD);默认确定性输出,--ai可选地使用模型将其重写为可读的发布说明散文;gitl digest [--days=N] [--repos=a,b,c]— 按作者/主题/文件生成活动摘要,支持并行处理多个仓库;交互式 TUI 查看器(--tui)。
一个简洁的 CLI 二进制文件加上一个 GitHub Action 包装器——无需服务器、数据库或托管密钥存储。BYOK(自带密钥)并支持多提供商:OpenAI 兼容 API、Ollama(本地/自托管)、Azure OpenAI、原生 Anthropic(Claude)、Google Gemini。无遥测。
状态:
v0.6.2已发布——所有三个命令都能在真实仓库上工作,并支持所有三种输出格式(md|text|json)。该 Action 将 AI 审查作为置顶 PR 评论发布,并根据风险评分进行门禁。发布二进制文件是交叉编译的,经过 cosign 签名,并受 SLSA L3 构建来源保护(参见 VERIFY.md)。
快速开始
需要 Go 1.22+ 和 git 在 PATH 中。
# build
go build ./...
# AI review of a commit range — streams tokens to the terminal in real time
GITL_API_KEY=sk-... go run ./cmd/gitl review HEAD~5..HEAD
# no key = deterministic offline review (heuristic risk, no network call)
go run ./cmd/gitl review HEAD~5..HEAD
# review staged (not yet committed) changes before `git commit`
go run ./cmd/gitl review --staged
# review a GitHub PR by number — requires the `gh` CLI (installed + authenticated);
# resolves base/head via gh, fetches `pull/N/head` locally when needed, and reviews
# the merge-base diff (base...head), same as GitHub shows
go run ./cmd/gitl review pr/42
# machine-readable output for CI + risk gating
go run ./cmd/gitl review HEAD~5..HEAD --format=json
go run ./cmd/gitl review HEAD~5..HEAD --fail-on=high # exit code 2 on high risk
# exit codes: 0 = ok (risk below --fail-on), 1 = tool/runtime error (git/LLM/
# config failure), 2 = the --fail-on risk gate triggered — CI can branch on 2
# estimate cost without making an API call
go run ./cmd/gitl review HEAD~5..HEAD --dry-run
# custom system-prompt template (e.g. your team's review policy) — set via
# config only (prompt.system_template_file); there is no --system-template flag
# see Configuration → Custom templates below
# skip the on-disk LLM cache (always call the model)
go run ./cmd/gitl review HEAD~5..HEAD --no-cache
# disable streaming (non-interactive, buffered output)
go run ./cmd/gitl review HEAD~5..HEAD --no-stream
# suppress the informational offline-mode notice on stderr (errors and the
# review output are unaffected) — also via GITL_QUIET=1 or output.quiet: true
go run ./cmd/gitl review HEAD~5..HEAD --quiet
# changelog from last tag (or full history if no tags) — no LLM by default
go run ./cmd/gitl changelog
go run ./cmd/gitl changelog v1.2.0..HEAD --format=json
# AI changelog: the model rewrites the grouped result as release-note prose and
# reclassifies significant non-conventional commits out of "Other". Without an API
# key (or on a malformed model response) it falls back to the deterministic
# changelog with a warning — never fails. --dry-run/--max-cost-usd/--no-cache work
# the same as for review.
GITL_API_KEY=sk-... go run ./cmd/gitl changelog --ai
# activity summary for the last N days — no LLM
go run ./cmd/gitl digest --days=14
# multi-repo digest: runs in parallel; one unreachable repo does not fail the rest
go run ./cmd/gitl digest --repos=../service-a,../service-b --format=json
# interactive TUI viewer for digest (requires a TTY)
go run ./cmd/gitl digest --days=14 --tui
go run ./cmd/gitl version
go run ./cmd/gitl --help
# tests
go test ./...安装:
# Go toolchain
go install github.com/akomyagin/gitl/cmd/gitl@latest
# Homebrew (macOS/Linux)
brew install akomyagin/tap/gitl
# npm — downloads the prebuilt binary for your platform from GitHub Releases
# and verifies its SHA256 checksum (no Go toolchain needed).
npx gitl-cli review HEAD~5..HEAD # or: npm install -g gitl-cli
# Or download a signed release binary from GitHub Releases (see VERIFY.md)Shell 补全
gitl 附带 cobra 生成的 bash、zsh、fish 和 PowerShell 补全。
Homebrew 安装会自动安装 bash/zsh/fish 补全(发布归档也包含在 completions/ 下)。否则,按需启用:
# bash (current shell)
source <(gitl completion bash)
# bash (persistent) — Linux
gitl completion bash > /etc/bash_completion.d/gitl
# zsh (persistent)
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——会补全其允许的值。
本地多提供商测试(Ollama)
docker-compose.yml 仅启动开发依赖——一个用于测试多提供商 LLM 客户端的本地 Ollama 实例(gitl 本身不进行容器化):
docker compose up ollamaRelated MCP server: grippy-code-review
配置
快速路径:gitl init 在仓库根目录写入一个带注释的入门 .gitl.yaml(除非使用 --force,否则拒绝覆盖现有文件;--output 可写入其他位置)。编辑它而不是从本节复制粘贴——以下内容是完整参考。
两个级别,按优先级合并:
标志 > 环境变量 > .gitl.yaml(仓库)> ~/.config/gitl/config.yaml(个人)。
仓库级别的 .gitl.yaml 作为团队共享策略提交(风险阈值、排除路径、变更日志类别)。如果没有密钥,gitl 将以确定性离线模式运行。
在离线模式下——或者当真实模型省略了有效的风险块且 gitl 回退到启发式时——风险头部会标注 *(heuristic)*(在 --format=json 中为 "heuristic": true),这样确定性评分就不会被误认为是模型自身的判断。
提供商(llm.provider)
# OpenAI-compatible API (default)
llm:
provider: "openai"
api_key: "" # or env GITL_API_KEY
base_url: "https://api.openai.com/v1"
model: "gpt-4o-mini"
# Ollama — local/self-hosted, no key, free
llm:
provider: "ollama"
base_url: "http://localhost:11434/v1"
model: "llama3.1"
# Azure OpenAI — custom auth/endpoint format
llm:
provider: "azure_openai"
api_key: "" # or env GITL_API_KEY
model: "gpt-4o-mini" # used only for cost estimation
azure_openai:
endpoint: "https://<resource>.openai.azure.com"
deployment: "<deployment-name>"
api_version: "2024-08-01-preview"
# Anthropic (native Claude Messages API)
llm:
provider: "anthropic"
api_key: "" # or env GITL_API_KEY
model: "claude-sonnet-4-6"
# base_url optional; defaults to https://api.anthropic.com
# Google Gemini (Google AI Studio)
llm:
provider: "gemini"
api_key: "" # or env GITL_API_KEY
model: "gemini-2.5-flash"
# base_url optional; defaults to https://generativelanguage.googleapis.com/v1beta流式输出(output.stream)
在交互式审查时(TTY 上的 md 或 text 格式),gitl 会实时将 token 流式输出到终端——无需等待完整响应。流式输出默认开启,并在 CI(非 TTY 标准输出)、--format=json 以及配置了自定义 output.template_file 时自动关闭(模板需要完整响应,因此审查会被缓冲并通过模板渲染)。
流式输出目前仅针对 OpenAI 兼容提供商(openai / ollama / azure_openai)实现。对于原生 anthropic 或 gemini 提供商,gitl 会透明地产生与单个缓冲响应相同的审查结果(无逐 token 输出),无论 output.stream / --no-stream 如何设置。
output:
stream: true # default; set false to always buffer按调用禁用:gitl review HEAD~5..HEAD --no-stream
颜色(output.color)
在交互式终端上,gitl review 会对头部中的风险级别进行着色(HIGH 红色,MEDIUM 黄色,LOW 绿色)。当标准输出不是 TTY(管道、CI 日志)时,颜色会自动关闭,并且永远不会出现在 --format=json 输出中。优先级从高到低:
设置了
NO_COLOR环境变量(任何值,甚至为空)——颜色关闭(no-color.org);配置中的
output.color: false(或GITL_OUTPUT_COLOR=false)——颜色关闭;标准输出不是 TTY——颜色关闭;
否则——颜色开启。
output:
color: true # default; set false to disable ANSI color安静模式(output.quiet)
如果没有 API 密钥,review 每次运行都会向 stderr 打印一条信息性通知“使用确定性离线审查”(changelog --ai 也会打印类似的回退通知)。在已知的离线上下文中——最明显的是 pre-commit 钩子,它会在每次提交时触发——该横幅是噪音。使用以下任一方式抑制它(每一层都可以独立开启抑制):
review/changelog上的--quiet标志;设置了
GITL_QUIET环境变量(任何值,甚至为空);配置中的
output.quiet: true(或GITL_OUTPUT_QUIET=true)。
--quiet 仅静默信息性横幅:错误、渲染的审查/变更日志(在标准输出上)以及 --fail-on 门禁永远不会受到影响。
output:
quiet: false # default; set true to suppress the offline noticesLLM 响应缓存(cache)
gitl review 将模型响应缓存到磁盘(提供商 + 模型 + 提示的 SHA-256)。相同的差异会立即重用缓存结果,无需 API 调用或费用。
cache:
enabled: true # default
ttl_hours: 24 # entries older than this are ignored缓存位于 ~/.cache/gitl/review/(符合 XDG 规范)。按调用禁用:gitl review HEAD~5..HEAD --no-cache
在 --format=json 中,每个审查产物都携带附加的运行元数据(schema_version 保持为 1;早于它的消费者会看到相同的文档加上两个新键):
{
"duration_ms": 1234,
"cache": { "hit": true, "tier": "local" }
}duration_ms— 整个审查运行的墙钟时间,以毫秒为单位(缓存命中仍会报告一个真实的、通常很小的数字)。cache.hit— 此审查是否来自 LLM 响应缓存而不是新的模型调用。cache.tier— 本次运行生效的缓存拓扑:none(离线模式、--no-cache、cache.enabled: false或ttl_hours <= 0)、local(仅磁盘)或tiered(磁盘 + 远程)。它报告配置的模式,而不是哪个后端提供了特定的命中。
故意没有 usage(token 计数)字段:gitl 不解析响应中的提供商使用情况,永久为空的字段比缺失更糟糕。当使用情况解析落地时,它将被添加——以附加方式,不增加 schema 版本。
共享远程缓存(cache.remote)— 可选加入
可选加入,默认关闭,自带后端: gitl 从不托管服务,并且在您配置之前不会向任何缓存发出网络请求。适用于 CI 冷启动——每个运行器都从空磁盘开始,但共享的 HTTP KV 端点允许一个运行器重用另一个运行器对相同差异的审查。
cache:
enabled: true
ttl_hours: 24
remote: # opt-in shared cache for CI cold starts (off by default)
url: https://cache.example.com/gitl # your endpoint; gitl hosts nothing
token_env: GITL_REMOTE_CACHE_TOKEN # env var holding an optional bearer token
timeout_ms: 3000配置后,本地磁盘缓存保持为第一层:读取先检查磁盘,然后检查远程(远程命中会回填到磁盘);写入同时进行。
协议是一个基于 HTTP 的简单键值存储——任何静态对象存储或小型处理器都可以:
GET {url}/{key}→200并返回 JSON 条目主体,或404= 未命中。任何其他状态、网络错误或超时都视为未命中。PUT {url}/{key}并将 JSON 条目作为请求主体(Content-Type: application/json)→ 任何2xx= 已存储。如果
token_env指定了一个具有非空值的环境变量,则两个请求都携带Authorization: Bearer <token>。token 本身永远不会从配置文件中读取(与GITL_API_KEY相同的纪律)。键是 64 字符的十六进制 SHA-256 字符串;值对服务器是不透明的。
安全契约: 任何远程故障(超时、5xx、端点不可达)都会静默降级为本地缓存 / 无缓存——它永远不会使审查失败。存储的条目仅包含模型的响应,由不透明的哈希键控:差异和提示文本永远不会到达远程缓存。早于 ttl_hours 的条目在客户端被忽略,无论服务器返回什么。
风险趋势(policy.risk_log_enabled)
每次 gitl review 运行都会将其风险结果(级别、范围、提供商、时间戳)追加到本地 JSONL 日志:$XDG_DATA_HOME/gitl/risk-history.jsonl(默认 ~/.local/share/gitl/risk-history.jsonl;Windows 上为 %AppData%\gitl\)。gitl digest 会读回它并显示每个仓库的 “风险趋势(最近 N 天)” 部分——按级别划分的审查数量、高风险方向(窗口的最近一半与较早一半相比)以及最近几次审查。在 --format=json 中,它作为可选的 risk_trend 字段出现(schema_version 保持为 1;早于它的消费者会看到相同的文档)。没有历史的仓库会直接省略该部分。
审查通过其 origin 远程 URL 与仓库关联(当没有 origin 时回退到工作树路径)。
限制: 历史记录仅限本地机器——它不会在 CI 运行器之间持久化(每个运行器都从冷磁盘开始),因此趋势是本地开发人员使用的功能,而不是 CI 的功能。
在配置中选择退出(没有 CLI 标志):
policy:
risk_log_enabled: false自定义模板(prompt.*_template_file / output.template_file)
独立的、仅配置的覆盖(它们都没有 CLI 标志):
prompt.system_template_file— 您自己的审查系统提示,用于引导模型的关注点(安全清单、架构约束、团队规则)。仅由gitl review使用:prompt: system_template_file: "./review-policy.md" # path relative to CWD审查系统提示模板可以访问
{{ .Commits }}、{{ .Diff }}、{{ .Range }}、{{ .Staged }}(参见internal/prompt/templates.go)。prompt.changelog_system_template_file— 您自己的变更日志系统提示,仅由gitl changelog --ai使用:prompt: changelog_system_template_file: "./changelog-policy.md" # path relative to CWD变更日志系统提示模板可以访问
{{ .Commits }}、{{ .Range }}、{{ .Grouped }}——不是{{ .Diff }}:changelog --ai基于提交元数据工作,没有差异,使用.Diff的审查形状模板在这里会失败。这正是两个键分开的原因:每个命令只读取自己的键,并且可以单独设置其中一个而不设置另一个。output.template_file— 您自己的**md格式渲染模板**,用于完成的审查产物:output: template_file: "./review-output.tmpl" # path relative to CWD输出模板具有
internal/render/render.go中的渲染模板函数(render.TemplateFuncs())。
信任说明:
prompt.*_template_file/output.template_file键可以由仓库级别的.gitl.yaml设置,而不仅仅是您的个人配置——因此对您不控制的克隆仓库运行gitl review可能会将其指向该同一仓库内的模板。这是团队共享审查策略的预期机制,而不是错误:这里的text/template无法读取任意文件或执行代码,但对待不受信任的仓库的.gitl.yaml应像对待其.git/hooks或构建脚本一样谨慎。
GitHub Action
gitl 可以作为 GitHub Action 接入:它会 AI 审查拉取请求的提交,并发布带有风险评分的评论,可选地在超过阈值时阻止合并。该 Action 从源代码构建 gitl(在固定版本上执行 go install)。如果您愿意,也可以从 GitHub Marketplace 添加。
将 .github/workflows/gitl-review.yml 添加到您的仓库:
name: gitl review
on:
pull_request:
permissions:
contents: read # for checkout
pull-requests: write # to post the review comment
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0 # required: without full history base..head won't resolve
- uses: akomyagin/gitl@v0.6.2
with:
gitl-api-key: ${{ secrets.GITL_API_KEY }} # BYOK, see below
fail-on: high # optional: block merge on high risk安全最佳实践:
仅通过
secrets.*提供密钥。gitl-api-key来自secrets.GITL_API_KEY(在 Settings → Secrets and variables → Actions 下设置),绝不硬编码在 YAML 中或提交到仓库。 如果未设置该 secret,Action 将以确定性的离线模式运行(无网络、无成本)。最小化
permissions:。 只需要pull-requests: write(用于发布评论)和contents: read(用于检出)——不要授予更广泛的权限。必须设置
fetch-depth: 0。 GitHub 在pull_request事件中提供base/headSHA, 但浅克隆无法解析base.sha..head.sha。fail-on默认为never。 该 Action 仅发布评论;除非你显式选择加入 (fail-on: high等),否则不会阻止合并——与 CLI(--fail-on)的“默认 WARN, 硬性门禁需显式选择加入”原则相同。当门禁触发时,任务以 gitl 的退出码2(风险门禁) 失败——真正的工具错误以1失败,因此下游步骤可以区分“有风险的变更”和“gitl 出错”。Diff 隐私。 在 CI 中,diff 被发送到所配置的任意 LLM 提供商 (默认:兼容 OpenAI 的 API)。对于私有代码,请使用自托管/企业级提供商 (Ollama、Azure OpenAI)——参见上文 Providers。
提供商选择。 默认情况下,Action 使用你配置中的提供商(如果未设置则为兼容 OpenAI 的 提供商)。要指定原生提供商,请传入
provider:(openai|ollama|azure_openai|anthropic|gemini), 以及可选的model:和base-url:,与gitl-api-key:一起使用。这三个都是可选的, 省略时会回退到你的.gitl.yaml/个人配置以及 gitl 的内置默认值——参见上文 Providers。示例:provider: anthropic并在secrets.GITL_API_KEY中提供 Claude 密钥。Secret 掩码。 GitHub 会自动将 runner 日志中的
secrets.*值掩码为***,但这并不是你在自己的工作流步骤中打印密钥的理由。
PR 描述风险摘要(选择加入)
使用 update-pr-description: true(默认 false)时,Action 还会在 PR 描述末尾维护
一个紧凑的风险摘要块——风险行加上指向完整审查评论的链接,每次运行都会更新:
- uses: akomyagin/gitl@v0.6.2
with:
gitl-api-key: ${{ secrets.GITL_API_KEY }}
update-pr-description: true这是选择加入的,因为编辑 PR 描述比置顶评论更具侵入性;不需要额外的权限——
发布评论所需的 pull-requests: write 同样覆盖 PR 正文。该块由
<!-- gitl-review-summary --> 标记对界定,只有标记之间的文本会被替换——
你在标记之外写的任何内容都不会被触碰。目前仅支持 GitHub(在 Gitea Actions 上被忽略)。
Gitea Actions(实验性)
同一个 action.yml 也可以在 Gitea Actions 上运行——
Gitea 的 runner 执行 GitHub 风格的复合 action,gitl 的 action 在运行时通过
Gitea 的 act_runner 注入到每个任务中的 GITEA_ACTIONS=true 变量来检测平台。
唯一平台相关的部分——发布置顶 PR 评论——通过 Gitea 的 REST API
(POST/PATCH /api/v1/repos/{owner}/{repo}/issues/...)使用 curl 完成,而不是
gh CLI(后者只支持 GitHub 的 API)。GitHub 用户不受影响:没有
GITEA_ACTIONS 时,action 的行为与之前完全一致。
将 .gitea/workflows/gitl-review.yml 添加到你的仓库(完整带注释的示例:
本仓库中的 .gitea/workflows/gitl-review.yml):
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; omit for offline mode要求:启用 Actions、较新的 act_runner(支持 node24)、以及提供 bash、git、curl、
jq 和 node 的 runner 镜像。GITL_API_KEY 放入 Gitea 的 Actions secrets 中,
绝不写入 YAML——与 GitHub 上相同的 BYOK 规则。
验证状态——在依赖此功能前请先阅读。 基于
curl的 REST 调用(列出评论、创建、更新、置顶检测)已针对真实的 Gitea 实例 (Docker 中的gitea/gitea)端到端运行——列表为空 → POST 创建 → 重新列出可找到 → PATCH 更新 → 仍然只有一条评论。这部分按文档所述正常工作。 尚未验证的是周围的act_runnerCI 上下文:GITEA_ACTIONS/GITHUB_API_URL/PR 事件负载在真实工作流运行中是否与假设完全一致 (这是对照 Gitea/act_runner/act-fork 源码交叉检查的,并未在实际任务中运行)。 在有人在真实的 Gitea Actions 中确认端到端绿色运行之前,请将 CI 触发路径视为实验性; 非常欢迎来自真实实例的 bug 报告。
GitLab CI(实验性)
gitl 还附带一个 GitLab CI/CD 组件——
templates/gitl-review.yml——镜像了 GitHub Action 的功能:
它使用 go install 在固定版本上安装 gitl,审查合并请求的范围
($CI_MERGE_REQUEST_DIFF_BASE_SHA..$CI_COMMIT_SHA),通过共享的平台无关
ci/comment.sh 渲染评论,并通过 GitLab 的 REST API 创建/更新
置顶 MR 评论(与 GitHub/Gitea 上相同的 <!-- gitl-review --> 标记)。该任务仅在合并请求流水线中运行。
该组件通过本仓库的发布时镜像发布在 GitLab CI/CD Catalog 中,
镜像位于 gitlab.com/alkom68/gitl(单向 GitHub → GitLab,
在每个发布标签时推送)。在 gitlab.com 上,将其作为目录组件引入:
# .gitlab-ci.yml (gitlab.com)
include:
- component: gitlab.com/alkom68/gitl/gitl-review@v0.6.2
inputs:
fail_on: "never" # default; set "high" to block risky MRs
# max_cost_usd: "0.50"
# gitl_version: "v0.6.2"在自托管的 GitLab 实例上,include:component 只能解析来自同一实例的组件——
请改用 include:remote 直接从 GitHub 引入模板(inputs 适用于远程引入):
# .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 变量(Settings → CI/CD → Variables,均需掩码,绝不写入 YAML):
GITL_API_KEY— BYOK LLM 密钥。可选:没有它时 gitl 运行确定性的 离线审查(无网络、无成本)。定义项目变量就足够了——它优先于组件空的gitl_api_keyinput 默认值。如果改用 input,请传入变量引用 (gitl_api_key: $MY_LLM_KEY),绝不要传字面密钥:input 值会被插值到流水线配置中。GITL_GITLAB_TOKEN— 用于发布 MR 评论的令牌(项目访问令牌或 PAT,api范围,Reporter 角色或更高;作为PRIVATE-TOKEN发送)。如果未设置, 任务会回退到CI_JOB_TOKEN(JOB-TOKEN头)——但在大多数 GitLab 配置中,CI_JOB_TOKEN无权访问 Notes API,因此回退预计会失败 (带有明确的错误消息,而不是静默跳过)。显式设置GITL_GITLAB_TOKEN才是可靠路径。
一个完整的带注释自测流水线——也是最接近完整用法示例的内容——
是 .gitlab-ci-selftest.yml(可作为本仓库 GitLab 镜像中的
.gitlab-ci.yml 运行)。
验证状态——在依赖此功能前请先阅读。 GitLab REST 调用 (列出 MR 评论 + 置顶标记检测、
POST创建、PUT更新)以及组件 YAML 本身 (spec:/inputs:插值、带 inputs 的include:local,通过 CI Lint API 验证) 已针对真实的本地 GitLab CE 实例(Docker 中的gitlab/gitlab-ce19.2.0)在真实的合并 请求上端到端验证——列表为空 → POST 创建 → 重新列出可找到 → PUT 更新 → 仍然 只有一条评论——使用了模板中的确切curl/jq命令。尚未验证的是实时流水线运行: 真实合并请求流水线中CI_MERGE_REQUEST_DIFF_BASE_SHA/CI_COMMIT_SHA/CI_JOB_URL的值是根据 GitLab 文档编写的,而非实际观察到的,并且CI_JOB_TOKEN回退被拒绝 是根据 GitLab 的 job-token 允许列表文档记录的,而非复现的。在有人确认端到端绿色运行之前, 请将流水线路径视为实验性;欢迎 bug 报告。
信任说明。 该组件在
gitl_version处从 GitLab 镜像 (gitlab.com/alkom68/gitl)下载ci/comment.sh并执行——没有 校验和/签名检查,与上面紧邻的go install ...@${gitl_version}行具有相同的信任边界 (同一仓库、同一引用)。此获取无论组件如何引入都会发生——Catalog 或include:remote——因为组件引入只附带 YAML 模板,而不附带组件仓库的文件, 因此无法在机制上避免此获取。从发布该组件的同一 GitLab 实例下载 (而不是从 GitHub)可保持同命名空间/同引用,这比跨主机获取更诚实的信任模型。 如果这对你的威胁模型很重要,请将gitl_version固定为提交 SHA 而不是标签(标签是可移动的)。
Bitbucket Pipelines(实验性)
Bitbucket 集成以 Pipe 形式提供——
而 pipe 按定义就是 Docker 镜像,因此与 GitHub/Gitea action 和 GitLab 组件
(纯 YAML 包装器)不同,这是一个自包含镜像:
bitbucket-pipe/Dockerfile 构建一个静态的 gitl
二进制文件,并内置共享的 ci/comment.sh 渲染器以及
入口点 bitbucket-pipe/pipe.sh。该 pipe 解析
PR 范围($BITBUCKET_PR_DESTINATION_COMMIT..$BITBUCKET_COMMIT),运行
gitl review --format=json,并通过 Bitbucket Cloud REST API 创建/更新
置顶 PR 评论(与其他平台相同的 <!-- gitl-review --> 标记)。变量参考:
bitbucket-pipe/pipe.yml。
镜像状态。 自
v0.5.2起发布在 Docker Hub 上,名为alkom68/gitl-review-pipe——发布工作流的docker-publish任务在每个发布标签时 推送:<version>和:latest。注册表中只存在0.5.2及更高版本: 更早的版本早于发布(0.5.0/0.5.1标签从未被推送),因此不要固定这些版本。
# bitbucket-pipelines.yml
pipelines:
pull-requests:
'**':
- step:
name: gitl review
clone:
depth: full # the default depth-50 clone may not contain the PR base commit
script:
- pipe: docker://alkom68/gitl-review-pipe:0.6.2
variables:
GITL_API_KEY: $GITL_API_KEY # BYOK; omit for offline review
GITL_BITBUCKET_TOKEN: $GITL_BITBUCKET_TOKEN # posts the PR comment
# FAIL_ON: "high" # default "never" — comment only, no gate
# MAX_COST_USD: "0.50"设置——两个受保护的仓库/工作区变量(Repository settings →
Pipelines → Repository variables;始终以 $VAR 形式引用,绝不在 YAML 中使用字面值):
GITL_API_KEY— BYOK LLM 密钥。可选:没有它时 gitl 运行确定性的 离线审查(无网络、无成本)。GITL_BITBUCKET_TOKEN— 用于发布 PR 评论的凭据:具有pullrequest:write范围的仓库/项目/工作区访问令牌,作为Authorization: Bearer发送。 替代方案:设置GITL_BITBUCKET_USER+GITL_BITBUCKET_APP_PASSWORD(具有pullrequest:write的应用密码)以使用 Basic 认证。如果两者都未配置, pipe 会以明确的错误消息快速失败——在花费任何 LLM 预算之前。
供应链说明(为何这与 GitLab 组件不同)。 该 pipe 不执行任何运行时获取的内容:
gitl二进制文件、ci/comment.sh和入口点都从单一源码树构建到带版本的镜像中。 GitLab 组件必须在网络上无完整性检查地下载ci/comment.sh(参见其上面的信任说明); 该 pipe 通过构造方式弥补了这一差距。
验证状态 — 在依赖本工具前请先阅读。 镜像构建和完整的容器内流程已在本地验证:从本仓库执行
docker build,然后针对一个真实的测试 git 仓库、以模拟的BITBUCKET_*变量执行docker run— 离线审查 → 生成正确的 stickycomment.md→ 创建评论(POST)、更新 sticky 评论(PUT,仍然恰好一条评论)以及--fail-on退出码传播,均针对本地 Bitbucket 评论 API 的 mock 进行了端到端测试;快速失败路径(缺少凭据/PR 变量)和错误范围上的回退提示也已在容器内测试。尚未验证的内容:任何涉及真实 Bitbucket 基础设施的部分 — 针对 api.bitbucket.org 的 REST 调用(请求结构取自 Atlassian 的 API 文档)、真实 PR 流水线中的确切预定义变量(BITBUCKET_PR_DESTINATION_COMMIT等是文档化的假设,而非实际观测值),以及 Pipelines 如何将克隆挂载到 pipe 容器中。在有人在真实 Bitbucket 工作区上确认一次绿色运行之前,请将实时流水线路径视为实验性功能;欢迎提交 bug 报告。
Pre-commit 钩子(本地)
gitl 附带一个 pre-commit 框架钩子,使得
gitl review --staged --quiet 在每次提交前自动运行 — 本地、离线、默认零成本(钩子清单中默认开启 --quiet,因此离线提示不会在每次提交时重复打印)。
在仓库的 .pre-commit-config.yaml 中添加:
repos:
- repo: https://github.com/akomyagin/gitl
rev: v0.6.2 # pin to a released tag
hooks:
- id: gitl-review然后运行 pre-commit install。该框架会自行构建 gitl 二进制文件(language: golang)并将环境缓存在 ~/.cache/pre-commit/ 下,因此构建成本只支付一次,而非每次提交都支付。
如需选择带成本上限的阻塞式钩子:
hooks:
- id: gitl-review
args: [--fail-on=high, --max-cost-usd=0.05] # opt-in: block on high risk, cap cost在环境中导出 GITL_API_KEY 以获得真实的 AI 审查;没有它,钩子将执行确定性的离线审查(无网络、无成本)。
需要了解的事项:
默认离线。 无 API 密钥、无网络、无每次提交成本。设置
GITL_API_KEY可选择真实的 AI 审查。默认不阻塞。 钩子打印审查结果但不会使提交失败 — 与 CLI/Action 相同的"默认 WARN,硬性门禁需显式选择"原则。添加
args: [--fail-on=high]以阻塞。延迟。 真实 API 审查需要几秒钟;保持离线以避开热路径,或用
--max-cost-usd设置上限。Diff 隐私。 使用真实密钥时,暂存的 diff 会发送到你配置的 LLM 提供商 — 对于私有代码,请使用自托管/企业级提供商(Ollama、Azure OpenAI),参见上文 Providers。
抑制离线提示。 清单默认传递
--quiet,因此每次提交时"使用确定性离线审查"的 stderr 提示会被静默;同样的开关也可在review/changelog上以--quiet/GITL_QUIET使用,或通过output.quiet: true在仓库范围内生效(MCP 服务器仅识别output.quiet/GITL_OUTPUT_QUIET— 它没有命令行标志,因此简短的GITL_QUIET别名在那里不适用)。错误和审查输出本身不受影响。
不使用 pre-commit 框架
普通的 git 钩子也可以:
# .git/hooks/pre-commit (chmod +x)
#!/usr/bin/env bash
set -euo pipefail
# Offline, non-blocking review of staged changes (WARN by default); --quiet
# suppresses the per-commit offline notice on stderr.
gitl review --staged --quiet || true
# To block the commit on high risk instead, replace the line above with:
# gitl review --staged --quiet --fail-on=highMCP 服务器
gitl mcp 将 gitl 作为 Model Context Protocol stdio 服务器运行 — 这是与上述 CLI/CI 用法不同的、额外的通道,用于在代理会话(Claude Desktop、Cursor、Windsurf 等)中交互式地使用 gitl,而不是通过 shell 调用。它暴露两个工具:
gitl_review— 与gitl review相同的审查引擎:range/pr/staged(恰好一个),可选的每次调用model覆盖。提供商和端点在设计上于服务器启动时固定:工具调用者是 AI 代理,可能被审查内容中的提示注入所操纵 — 每次调用的base_url会让恶意提交重定向请求并泄露真实的 API 密钥。始终返回结构化的 JSON 工件(无 md/text 渲染、无流式输出 — 工具结果是原子的)。risk.level作为数据返回;MCP 模式中没有--fail-on,因为没有进程退出码可供门禁。gitl_digest— 与gitl digest相同:days(默认 7),可选的repos。没有显式的repos参数时,该工具只摘要服务器的当前工作目录(加上.gitl.yaml中配置的digest.repos,如果配置了的话)— 它绝不会自行遍历任意路径。显式的repos参数按原样处理(调用代理已经通过自己的工具拥有文件系统访问权限;这不是访问控制边界,只是一个"不让用户意外"的默认行为)。
添加到你的 MCP 客户端配置中(Claude Desktop、Cursor 等):
{
"mcpServers": {
"gitl": {
"command": "gitl",
"args": ["mcp"]
}
}
}配置在启动时以与普通命令相同的方式加载一次(.gitl.yaml + 个人配置 + GITL_* 环境变量,从启动 gitl mcp 的目录加载)。没有密钥时,工具调用以与 CLI 相同的确定性离线模式运行。stdout 保留给 MCP 协议 — 那里永远不会写入任何人类可读的内容;警告输出到 stderr。
许可证
MIT。
This server cannot be deployed
Maintenance
Related MCP Connectors
AI-native git hosting — repos, PRs, issues, CI gates, and AI code review over MCP (60 tools).
Team memory for AI coding agents and code reviews, reviewed by humans and served over MCP.
Zero-secret MCP gateway for AI agents: risk-scored, audited calls with human-in-the-loop approval.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
Related MCP Servers
- AlicenseAqualityCmaintenanceA local Git intelligence MCP server that provides deep repository analytics including hotspots, temporal coupling, knowledge maps, churn analysis, and risk scoring for AI agents.1212MIT
- AlicenseNot gradedqualityCmaintenanceOpen-source AI code review MCP server for local git diff auditing with deterministic security rules and AI-powered analysis using any OpenAI-compatible model.4MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for automated code review using AI agents. It analyzes code diffs or file paths for bugs, security issues, and style violations.MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for AI code provenance, enabling traceability of file changes to AI agents, sessions, and prompts, plus reporting on AI-generated code activity.2 npmMIT