Commiti
AI-powered commit message and pull request description generator for Git repositories, using Google AI models.
What It Does
Commiti helps you:
- Generate conventional commit messages from staged changes.
- Generate structured pull request descriptions from branch diffs.
- Review and optionally edit generated commit messages before writing to Git history.
- Open a prefilled PR/MR page in your browser for GitHub, GitLab, or GitBucket (no provider API token required).
- Preserve semantic diff quality on large changes using file-aware clipping that keeps file headers and hunk markers.
Requirements
- Ruby 3.2+
- Git
- Google AI API key
- A Git repository as your working directory
Install Dependencies (from source)
bundle install
CLI Usage
bundle exec ruby -Ilib bin/commiti [options]
Or after gem installation:
commiti [options]
Configuration
Commiti uses a single configuration approach: environment variables.
Set variables in your shell, CI secret manager, or local .env file (in your project):
GOOGLE_API_KEY=your_google_ai_key
# Optional overrides:
# COMMITI_MODEL=gemma-4-31b-it
# COMMITI_CANDIDATES=1
# COMMITI_BASE_BRANCH=main
# COMMITI_NO_COPY=false
# COMMITI_AUTO_SPLIT=false
GEMINI_API_KEY is also accepted as an alias for GOOGLE_API_KEY.
You can copy .env.example as a starting point.
Your API key is sent directly from your local process to Google's API.
Commiti does not store it and does not proxy requests through any Commiti server.
Never commit .env to git.
Options
--type TYPEwhereTYPEiscommitorpr(default:commit)--base BRANCHbase branch for PR diff (default:main)--no-copyprint output only, skip clipboard copy--candidates NgenerateNoutput candidates (1-5, default:1)--auto-splitauto-group staged changes into multiple connected commits (commit flow only)-h,--helpshow help
Commit Flow (--type commit)
By default, Commiti creates a single commit from staged changes.
Use --auto-split to let Commiti group connected file changes into multiple atomic commits.
- Shows
git status --short. - Asks for confirmation before staging (
git add -A). - Ensures there are staged changes.
- Reads staged diff and generates commit message candidate(s).
- If the AI draft misses a conventional commit prefix, Commiti auto-normalizes it to a valid conventional subject.
- If
--candidatesis greater than1, shows numbered candidates and asks you to select one. - Shows selected message and asks:
Commit with this message? [y/e/N]y: commit nowe: open editor, then validate and re-confirmN: skip commit
- Writes commit with
git commit --file <tempfile>.
Commit Message Validation
- First line must use a conventional commit prefix (e.g.
feat:,fix:). - First line must be 100 characters or fewer.
Why --file instead of -m
Multi-line messages and special characters are safer with git commit --file, avoiding shell quoting edge cases.
Editor Selection
Commit edit mode uses:
VISUALEDITOR- Fallback:
notepadon Windows,vion non-Windows
PR Flow (--type pr)
- Reads branch diff:
git diff <base>...HEAD. - Generates PR description with these sections:
## Summary## Motivation## Changes Made## Testing Notes
- Builds provider compare/MR URL with prefilled title/body using query params.
- GitHub: compare URL with
quick_pull=1(opens the PR form directly) - GitBucket: compare URL with
expand=1 - GitLab: new merge request URL
- If the URL would exceed safe browser/provider limits, Commiti drops description prefill automatically and keeps the shortest usable URL.
- GitHub: compare URL with
- Asks before opening browser.
The tool opens a browser URL only. It does not call provider APIs.
Diff Context Protocol
When a diff exceeds internal size limits, Commiti clips and summarizes using file-aware rules:
- Keeps full
diff --gitfile headers where possible. - Preserves
@@ ... @@hunk headers before clipping hunk bodies. - Includes as many complete files/hunks as fit in the limit, then appends a clipping notice.
- Summarizes large chunks asynchronously and in batches to reduce total LLM round trips.
- Falls back to deterministic file-level summaries if model summarization times out.
This improves semantic quality for AI generation compared with naive truncation.
Examples
Generate commit message and commit interactively:
bundle exec ruby -Ilib bin/commiti --type commit
Generate multiple commit message candidates and pick one:
bundle exec ruby -Ilib bin/commiti --type commit --candidates 3
Generate PR description against develop:
bundle exec ruby -Ilib bin/commiti --type pr --base develop
Print only, do not copy to clipboard:
bundle exec ruby -Ilib bin/commiti --type pr --no-copy
Implementation Overview
Main entrypoint and flow orchestration:
bin/commiti: CLI parsing and flow dispatchlib/flows/base_flow.rb: shared generation pipeline and quality checkslib/flows/commit_flow.rb: commit-specific staging/edit/commit interactionslib/flows/pr_flow.rb: PR-specific URL generation/open flow
Core services:
lib/services/git_reader.rblib/services/git/git_reader.rb: Reads staged diff and branch diff, applies file-aware clipping, provides recent commits helper.lib/services/git/git_writer.rb: Reads status/staged state, stages (git add -A), commits with message file (git commit --file), reads branch and origin remote.lib/services/git/diff_parser.rb: Parses diff blocks and derives change metadata.lib/services/git/pr/pr_opener.rb: Parses GitHub/GitLab/GitBucket remotes, builds provider-specific PR/MR URL, opens browser cross-platform.
lib/services/google_client.rb: Sends generation requests to Google Generative Language API.lib/services/diff_summarization/diff_summarizer.rb: Orchestrates large-diff summarization and summary combine.lib/services/diff_summarization/batch_runner.rb: Runs asynchronous, batched per-file summarization jobs.lib/services/diff_summarization/fallback_builder.rb: Builds deterministic summaries when model summarization fails or times out.
lib/services/helpers/config_loader.rb: Loads configuration from environment variables.lib/services/helpers/prompt_builder.rb: Builds strict system/user prompts for commit and PR modes.lib/services/helpers/interactive_prompt.rb: Handles confirmation prompts, candidate selection, editor loop, and commit message validation.lib/services/helpers/clipboard.rb: Provides cross-platform clipboard support.lib/services/helpers/spinner.rb: Displays a spinner for long-running operations.
lib/services/message_generator.rb: Generates commit and PR messages with quality checks.lib/services/message_presenter.rb: Presents generated messages to the user.lib/services/flow_context_builder.rb: Builds the context for different Commiti flows.lib/services/git/commit/commit_staging.rb: Handles staging changes for a commit.lib/services/git/commit/commit_execution.rb: Executes the git commit command.
Service loading:
lib/commiti.rbrequires all service modules.
Error Handling
The CLI reports user-friendly errors for common cases such as:
- No changes/staged changes
- Invalid or missing Git data
- Google AI API connectivity/authentication failures
- Summarization timeouts on large diffs (automatically falls back to a deterministic summary and continues)
- Browser open failures
Notes
- The default model is
gemma-4-31b-itinGoogleClient. - PR browser URL body payloads are URL-encoded with
URI.encode_www_form. - You can tune summarization worker concurrency with
DIFF_SUMMARY_WORKERS.