Gerrit CLI built with Bun.
- LLM-Friendly: XML output for AI/automation pipelines
- Interactive UI: Terminal UI for change selection and navigation
- Effect-based: Robust error handling and functional architecture
# Install Bun runtime
curl -fsSL https://bun.sh/install | bash
# Install ger
bun install -g @aaronshaf/gerger setupThis will prompt for your Gerrit credentials:
- Gerrit host URL
- Username
- HTTP password (from Gerrit settings)
# Check your connection status
ger status
# View your changes
ger mine
# View incoming reviews
ger incoming
# View a specific change
ger show 12345
# Add a comment
ger comment 12345 -m "LGTM"
# Get diff for review
ger diff 12345
# Extract URLs from messages (e.g., Jenkins build links)
ger extract-url "build-summary-report" | tail -1
# Check CI build status (parses build messages)
ger build-status 12345 # Returns: pending, running, success, failure, or not_found
ger build-status # Auto-detects from HEAD commit
# Watch build status until completion (like gh run watch)
ger build-status 12345 --watch
ger build-status --watch --exit-status && deploy.sh
# AI-powered code review (requires claude, llm, or opencode CLI)
ger review 12345
ger review 12345 --dry-run # Preview without postingger status
ger status --pretty# Complete change info with metadata, diff, inline comments, and review activity
ger show 12345
ger show 12345 --pretty# Your changes
ger mine
ger mine --pretty
# Incoming reviews
ger incoming
ger incoming --pretty
# Workspace changes (local branch tracking)
ger workspace
ger workspace --pretty# Using -m flag
ger comment 12345 -m "LGTM"
# Piping plain text (becomes overall comment message)
echo "Review text" | ger comment 12345
cat review.txt | ger comment 12345# Single line comment (line numbers refer to post-merge view)
ger comment 12345 --file src/main.ts --line 42 -m "Consider error handling"
# Mark as unresolved
ger comment 12345 --file src/main.ts --line 42 -m "Fix this" --unresolvedThe batch comment feature accepts a JSON array of comment objects. Each comment can target specific lines, ranges, or sides of the diff.
[
{
"file": "path/to/file.js", // Required: File path
"line": 42, // Optional: Line number (omit when using range)
"message": "Your comment", // Required: Comment text
"side": "REVISION", // Optional: "PARENT" or "REVISION" (default: REVISION)
"range": { // Optional: Comment on multiple lines or characters
"start_line": 10,
"end_line": 20,
"start_character": 0, // Optional: Character position (0-indexed)
"end_character": 80
},
"unresolved": true // Optional: Mark as unresolved (default: false)
}
]# Basic batch comments
echo '[
{"file": "src/main.ts", "line": 10, "message": "Add type annotation"},
{"file": "src/utils.ts", "line": 25, "message": "Extract to constant"},
{"file": "src/api.ts", "line": 100, "message": "Handle error", "unresolved": true}
]' | ger comment 12345 --batch
# Comment on different sides of the diff
# PARENT: The original code before changes
# REVISION: The new code after changes
echo '[
{"file": "src/Calculator.java", "line": 5, "side": "PARENT", "message": "Why was this removed?"},
{"file": "src/Calculator.java", "line": 5, "side": "REVISION", "message": "Good improvement"}
]' | ger comment 12345 --batch
# Range comments for blocks of code
echo '[
{
"file": "src/Service.java",
"range": {"start_line": 50, "end_line": 55},
"message": "This entire method needs refactoring"
},
{
"file": "src/Service.java",
"range": {"start_line": 10, "start_character": 8, "end_line": 10, "end_character": 25},
"message": "This variable name is confusing"
}
]' | ger comment 12345 --batch
# Combined features: range + side + unresolved
echo '[
{
"file": "src/UserService.java",
"range": {"start_line": 20, "end_line": 35},
"side": "PARENT",
"message": "Why was this error handling removed?",
"unresolved": true
},
{
"file": "src/UserService.java",
"range": {"start_line": 20, "end_line": 35},
"side": "REVISION",
"message": "New error handling looks good, but consider extracting to a method"
}
]' | ger comment 12345 --batch
# Load comments from a file
cat comments.json | ger comment 12345 --batch# View all comments with diff context
ger comments 12345
ger comments 12345 --prettyExtract URLs from change messages and comments for automation and scripting:
# Extract URLs from current HEAD commit's change (auto-detect)
ger extract-url "build-summary-report"
# Get the latest build URL (using tail)
ger extract-url "build-summary-report" | tail -1
# Get the first/oldest build URL (using head)
ger extract-url "jenkins" | head -1
# For a specific change (using change number)
ger extract-url "build-summary" 12345
# For a specific change (using Change-ID)
ger extract-url "build-summary" If5a3ae8cb5a107e187447802358417f311d0c4b1
# Chain with other tools for specific change
ger extract-url "build-summary-report" 12345 | tail -1 | jk failures --smart --xml
# Use regex for precise matching
ger extract-url "job/Canvas/job/main/\d+/" --regex
# Search both messages and inline comments
ger extract-url "github.com" --include-comments
# JSON output for scripting
ger extract-url "jenkins" --json | jq -r '.urls[-1]'
# XML output
ger extract-url "jenkins" --xml- Change detection: Auto-detects Change-ID from HEAD commit if not specified, or accepts explicit change number/Change-ID
- Pattern matching: Substring match by default, regex with
--regex - Sources: Searches messages by default, add
--include-commentsto include inline comments - Ordering: URLs are output in chronological order (oldest first)
- Composable: Pipe to
tail -1for latest,head -1for oldest
# Get latest Jenkins build URL for a change
ger extract-url "jenkins.inst-ci.net" | tail -1
# Find all GitHub PR references
ger extract-url "github.com" --include-comments
# Extract specific build job URLs with regex
ger extract-url "job/[^/]+/job/[^/]+/\d+/$" --regexCheck the CI build status of a change by parsing Gerrit messages for build events and verification results:
# Check build status for a specific change
ger build-status 12345
# Output: {"state":"success"}
# Auto-detect change from HEAD commit
ger build-status
# Use in scripts with jq
ger build-status | jq -r '.state'Like gh run watch, you can poll the build status until it reaches a terminal state:
# Watch until completion (outputs JSON on each poll)
ger build-status 12345 --watch
# Output:
# {"state":"pending"}
# {"state":"running"}
# {"state":"running"}
# {"state":"success"}
# Auto-detect from HEAD commit
ger build-status --watch
# Custom polling interval (check every 5 seconds, default: 10)
ger build-status --watch --interval 5
# Custom timeout (60 minutes, default: 30 minutes)
ger build-status --watch --timeout 3600
# Exit with code 1 on build failure (for CI/CD pipelines)
ger build-status --watch --exit-status && deploy.sh
# Trigger notification when done (like gh run watch pattern)
ger build-status --watch && notify-send 'Build is done!'
# Extract final state in scripts
ger build-status --watch | tail -1 | jq -r '.state'{"state": "success"}pending: No "Build Started" message found yetrunning: "Build Started" found, but no verification result yetsuccess: Verified +1 after most recent "Build Started"failure: Verified -1 after most recent "Build Started"not_found: Change does not exist
0: Default for all states (likegh run watch)1: Only when--exit-statusflag is used AND build fails2: Timeout reached in watch mode3: API/network errors
- Fetches all messages for the change
- Finds the most recent "Build Started" message
- Checks for "Verified +1" or "Verified -1" messages after the build started
- Returns the appropriate state
- In watch mode: polls every N seconds until terminal state or timeout
- CI/CD integration: Wait for builds before proceeding with deployment
- Automation: Trigger actions based on build results
- Scripting: Check build status in shell scripts
- Monitoring: Poll build status for long-running builds with watch mode
# Full diff
ger diff 12345
ger diff 12345 --pretty
# List changed files
ger diff 12345 --files-only
# Specific file
ger diff 12345 --file src/main.ts# Open in browser
ger open 12345
# Abandon
ger abandon 12345
ger abandon 12345 -m "Reason"The ger review command provides automated code review using AI tools (claude, llm, or opencode CLI).
# Full AI review with inline and overall comments
ger review 12345
# Preview what would be posted without actually posting
ger review 12345 --dry-run
# Show debug output including AI responses
ger review 12345 --debugThe review command performs a two-stage review process:
- Inline comments: Specific code issues with line-by-line feedback
- Overall review: High-level assessment and recommendations
Requirements:
- One of these AI tools must be installed:
claude,llm, oropencode - Gerrit credentials must be configured (
ger setup)
# Review with AI
ger diff 12345 | llm "Review this code"
# AI-generated comment
llm "Review change 12345" | ger comment 12345
# Complete change analysis
ger show 12345 | llm "Summarize this change and its review status"
# Automated approvals
echo "LGTM" | ger comment 12345<?xml version="1.0" encoding="UTF-8"?>
<comment_result>
<status>success</status>
<change_id>12345</change_id>
<message><![CDATA[LGTM]]></message>
</comment_result>Comment posted successfully
Change: Fix authentication bug (NEW)
Message: LGTM
To upgrade gi to the latest version:
bun update -g @aaronshaf/gerAfter upgrading, you may want to review new configuration options:
ger setup # Review and update your configurationFor local development:
git clone https://github.com/aaronshaf/ger
cd ger
bun install
# Run locally
bun run dev
# Run tests
bun test
bun run test:coverage
# Type checking
bun run typecheck
# Linting
bun run lint- Bun - Runtime and package manager
- Effect - Type-safe error handling and functional architecture
- TypeScript - With isolatedDeclarations
- Ink - Terminal UI components
- Commander - CLI argument parsing
MIT