Provider-agnostic code review toolkit for GitLab merge requests
Project description
git-review-cli
Provider-agnostic code review toolkit. Gathers merge/pull request data, verifies file ownership, runs analysis, and outputs structured reports — all from the CLI.
Providers
| Provider | Status | Backend |
|---|---|---|
| GitLab | Implemented | glab CLI |
| GitHub | Planned | gh CLI |
Currently implemented: GitLab. The provider/formatter/analyzer architecture
makes adding new forges straightforward — one file implementing BaseProvider.
Why not just the native CLI?
The same workflow applies regardless of provider. Compared to running raw
glab/gh commands:
| Raw CLI | git-review-cli |
|---|---|
| 4+ commands to gather MR/PR context | Single command |
| Raw JSON diffs, hard to scan | Structured markdown table |
| All files in diff treated equally | Ownership: MR commits vs branch drift |
| Lockfiles, binaries clutter the view | Auto-excluded noise files |
| No analysis | Deep mode: large changes, configs, missing tests |
| Full URL required every time | Shorthand: git-review-cli 123 |
| Must manually checkout branch | Auto-checkout branch locally |
| Separate commands for notes | --post writes + posts in one step |
Before: raw glab output
$ glab api projects/org%2Frepo/merge_requests/123/diffs --paginate
[{"old_path":"src/api/handler.go","new_path":"src/api/handler.go",
"diff":"@@ -12,7 +12,9 @@ func ...\n- old code\n+ new code\n...
"new_file":false,"renamed_file":false,"deleted_file":false},
{"old_path":"package-lock.json","new_path":"package-lock.json",
"diff":"@@ -1,500 +1,520 @@ ...",
"new_file":false,...}]
Hard to scan. Manual cross-reference with glab api .../commits to check ownership.
Lockfiles and noise mixed in.
After: git-review-cli output
$ git-review-cli https://gitlab.com/org/repo/-/merge_requests/123
# MR !123 — Add healthcheck endpoint
- **Author:** Jane Doe
- **State:** opened
- **Source branch:** `feat/healthcheck`
- **Target branch:** `main`
### Description
Adds a /health endpoint with DB ping.
## Commits
- `a1b2c3d4` Add healthcheck handler (Jane Doe)
## Changed Files
| File | Changes | Owned by MR |
|------|---------|-------------|
| `src/api/handler.go (new)` | +45/-0 | ✅ 1 commit(s) |
| `src/api/handler_test.go (new)` | +30/-0 | ✅ 1 commit(s) |
| `package-lock.json` | +520/-500 | 🚫 excluded |
_3 files: 2 owned, 0 not owned, 1 excluded_
## Existing Comments
_2 non-system comments on MR_
One command. Clean table. Ownership verified. Noise filtered.
Architecture
src/
├── cli.py # CLI entry point
├── git.py # Shared git operations
├── providers/ # Code forge backends
│ ├── base.py # Abstract provider interface
│ └── gitlab.py # GitLab via glab CLI
├── formatters/ # Output plugins
│ ├── base.py # Abstract formatter interface
│ ├── markdown.py # Full / caveman markdown
│ └── json.py # Machine-readable JSON
├── analyzers/ # Analysis plugins
│ ├── ownership.py # File ownership verification
│ └── patterns.py # Pattern-based findings
└── __version__.py
Adding a new provider (e.g. GitHub)
- Implement
providers/base.py::BaseProvider - Add platform detection in
BaseProvider.resolve() - That's it — formatters and analyzers work with any provider's data
Requirements
- Python 3.8+
- glab (
brew install glab) - Authenticated to GitLab (
glab auth login)
Installation
pip install git-review-cli
Or symlink directly into your PATH:
ln -s $(pwd)/src/cli.py ~/.local/bin/git-review-cli
Usage
Arguments
git-review-cli <input> [options]
| Argument | Required | Description |
|---|---|---|
input |
Yes | Full MR URL (https://gitlab.com/org/repo/-/merge_requests/123) or just the MR number (123) for shorthand mode |
Shorthand mode auto-detects the repo from the current directory's git remote get-url origin. Works from any GitLab repo clone.
Options
| Flag | Description |
|---|---|
--json |
Output raw JSON instead of markdown. Useful for piping into jq or feeding to other tools. Contains MR metadata, commits, and changed files with additions/deletions. |
--caveman |
Concise markdown output. Skips commit list, skips deep analysis. Just MR metadata + changed files table. Ideal for quick scans. |
--deep |
Full analysis markdown output. Includes commit list, categorized findings (large changes, config/infra changes, missing tests, all changes grouped by category). Mutually exclusive with --caveman. |
--post <file> |
Post the contents of a markdown file as a comment on the MR. The file is read as-is and posted via glab mr note. The review file content is also appended to stdout so you can review before posting. |
--base <branch> |
Override the base branch for git diff operations. Defaults to the MR's target branch from the API. Useful when the target branch differs from what's configured in the remote (e.g., a custom release/ branch). |
--version |
Print version and exit. |
Examples
# Full MR URL — works from any directory
git-review-cli https://gitlab.com/org/repo/-/merge_requests/123
# Shorthand number — auto-detects repo from git origin
git-review-cli 123
# Quick scan, no fluff
git-review-cli 123 --caveman
# Deep dive with analysis
git-review-cli 123 --deep
# JSON for scripting
git-review-cli 123 --json | jq .files[].path
# Custom base branch
git-review-cli 123 --base release/2026-q3
# Write and post a review in one step
cat > /tmp/review-123.md << 'REVIEW'
## Review findings
- Tests cover the new endpoint
- Consider extracting the helper to a shared module
REVIEW
git-review-cli 123 --post /tmp/review-123.md
Output
The default markdown output includes:
- MR metadata (title, author, state, branches, description)
- Commit list
- Changed files table with ownership verification (owned / not owned / excluded)
- Existing comments summary
--deepadds categorized findings (large changes, config changes, missing tests)
File Ownership Verification
| Tag | Meaning |
|---|---|
| N commit(s) | File was touched by N commits in this MR |
| not owned | File exists in diff but not in any MR commit (branch drift) |
| excluded | Noise file (lockfiles, binaries, etc.) |
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Usage / parse error |
| 2 | glab not found |
| 3 | Git operation failed |
| 4 | Posting failed |
Planned
- GitHub provider —
ghCLI backend. ImplementsBaseProviderto fetch PR metadata, diffs, commits, and reviews. All existing formatters, analyzers, and CLI flags work unchanged. Estimated: ~80 lines of new code.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file git_review_cli-1.0.5.tar.gz.
File metadata
- Download URL: git_review_cli-1.0.5.tar.gz
- Upload date:
- Size: 16.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c231e5dc5a9e8b2c816041b0a4e07e06771af09d113b8f1b42d03144cd7e43b
|
|
| MD5 |
7b6dfca40c94b9fff3571565b3fe72e3
|
|
| BLAKE2b-256 |
e0d6c8cf241a03fb6e7d6c48b3afd3b1f90101cde544a79467840b6d422716b3
|
File details
Details for the file git_review_cli-1.0.5-py3-none-any.whl.
File metadata
- Download URL: git_review_cli-1.0.5-py3-none-any.whl
- Upload date:
- Size: 17.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c09701c0c590bf413c752086af43eb0253bec91c806d94bdb57d678b9025333
|
|
| MD5 |
6adf2a9ec84a9fff7d977578487189c0
|
|
| BLAKE2b-256 |
1736058b09dad4365b5edc1abc0a063fdb6cb76dca00da17f52fd6c44f5a632d
|