git-ship
v1.3.0
Published
AI-powered git workflow CLI: auto-group commits, fetch Linear context, run code review, and push
Downloads
282
Maintainers
Readme
Stop writing commit messages. git-ship reads your diffs, groups related changes into logical commits, writes conventional commit messages using AI, runs a code review, and pushes — all in one command.
Table of Contents
- Why I Built This
- How It Works
- Install
- Quick Start
- Usage
- Configuration Commands
- What Makes It Different
- Issue Tracker Integration
- Commit Message Structure
- Branch Parsing
- Commit Grouping
- Ignore Patterns
- Interactive File Selection
- Code Review
- Pull Request Creation
- Configuration
- Graceful Degradation
- Requirements
- License
Why I Built This
Every developer knows the routine: you've been heads-down on a feature for hours, touching fifteen files across four concerns. Now it's time to commit. You stare at git diff --stat, mentally sort files into groups, write conventional commit messages, stage carefully, and hope you didn't mix a migration with a test change. Then you do it again for the next group. And the next.
Most of the time, you give up and write git commit -am "update stuff". The commit history turns into noise. When someone needs to bisect a bug or review what changed, the history is useless.
I built git-ship because the commit–review–push workflow felt like it should be one step. The AI is good at reading diffs and understanding which changes belong together. The branch name already tells you what you're working on. The review tool is already installed. Why am I the glue between all of these?
Now I run gs, review the plan, and hit enter. Clean history, every time.
How It Works
$ git-ship
[1/8] Detect branch → parse issue ID from branch name (e.g., feat/ENG-123-...)
[2/8] Fetch issue context → pull from Linear, Jira, Asana, or enter plain text
[3/8] Collect changes → pick files interactively, then parse structured diffs
[4/8] Group into commits → heuristic pre-group, then AI refines into revertable commits
[5/8] Review commit plan → accept / edit messages / regroup / cancel
[6/8] Code review → CodeRabbit, Devin, Codex, or Graphite
[7/8] Push to remote
[8/8] Create pull request → AI-generated PR with summary, problem, solution, impactYou stay in control. Every step is interactive — review the plan, edit messages, regroup files, or cancel at any point.
Install
npm install -g git-shipQuick Start
On first run, git-ship launches an interactive setup wizard:
$ gs
Welcome to git-ship! Let's set up your configuration.
1. AI Provider Configuration
→ Choose OpenAI, Anthropic, or Gemini
→ Enter your API key (saved to shell profile)
2. Issue Tracker Integration
→ Linear (recommended) - automatic issue fetching
→ Jira (experimental) - requires base URL and API token
→ Asana (experimental) - requires access token
→ Plain Text - enter requirements manually each time
→ None - commits based on diffs only
3. Code Review Tool (Optional)
→ Choose Graphite, CodeRabbit, Codex, Devin, or skip
4. Commit Settings
→ Max commit header length (body has no limit)Configuration is saved globally (~/.config/gitship/config.json) and works across all repos.
Usage
git-ship # Full interactive flow
gs # Shorthand alias
gs --dry-run # Preview commit plan without executing
gs --no-review # Skip code review
gs --issue ENG-123 # Manually specify issue ID
gs --setup # Re-run setup wizard
gs config # View current configuration
gs config set <key> <value> # Update a specific setting
gs pr # Create a PR for the current branch
gs pr --draft # Create as draft PR| Flag | Description |
| ---------------------- | ----------------------------------------------------------------- |
| -h, --help | Show all available commands with descriptions |
| -d, --dry-run | Show commit plan without executing |
| -v, --verbose | Enable debug logging |
| --review-tool <tool> | Override review tool (coderabbit, devin, codex, graphite) |
| --no-review | Skip code review |
| -i, --issue <id> | Manually specify issue ID |
| --setup | Re-run setup wizard to update API keys or configuration |
| --readme | Display the full README documentation in terminal |
Configuration Commands
Quickly view or update settings without re-running the full setup wizard:
# View current configuration
gs config
gs config show
gs config show --json
# Update specific settings
gs config set commits.headerLength 50
gs config set ai.provider anthropic
gs config set ai.model claude-sonnet-4-20250514
gs config set issueTracker.provider plain
gs config set review.enabled false
# Show config file paths
gs config pathAvailable Config Keys
| Key | Values | Description |
| ------------------------- | ------------------------------------------ | ---------------------------- |
| commits.headerLength | 20 - 200 | Max commit header length |
| commits.conventional | true, false | Use conventional commits |
| commits.includeIssueRef | true, false | Include issue ref in commits |
| issueTracker.provider | linear, jira, asana, plain, none | Issue tracker to use |
| ai.provider | openai, anthropic, gemini | AI provider for analysis |
| ai.model | Model name string | AI model to use |
| review.enabled | true, false | Enable code review |
| review.tool | coderabbit, devin, codex, graphite | Code review tool |
What Makes It Different
| | |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| AI commit grouping | Produces small, reviewer-friendly commits that are each safe to revert — powered by OpenAI, Anthropic, or Gemini with heuristic fallback |
| Multi-tracker support | Works with Linear, Jira, Asana, or plain text requirements — not locked to one platform |
| Rich commit messages | Header (limited length) + body (detailed explanation) + footer (requirement mapping) |
| Code review gate | Runs CodeRabbit, Devin, Codex, or Graphite before pushing. Critical findings block the push. |
| Conventional commits | Enforces type, scope, imperative mood, configurable length — no more inconsistent commit history |
| Smart file filtering | Automatically ignores node_modules, .env*, dist, .DS_Store — configurable via ignorePatterns |
| Interactive file picker | Choose exactly which changed files to include — skip local config tweaks or cherry-pick files across branches |
| Global + local config | One-time setup works across all repos; override per-repo when needed |
Issue Tracker Integration
git-ship supports multiple issue tracking systems to provide context for better commit messages:
Linear (Recommended)
Automatically fetches issue details using your LINEAR_API_KEY:
# During setup, or manually:
gs config set issueTracker.provider linearJira (Experimental)
Requires your Jira instance URL and API credentials:
# Environment variables needed:
export JIRA_EMAIL="[email protected]"
export JIRA_API_TOKEN="your-api-token"
# Config:
gs config set issueTracker.provider jiraConfigure your Jira base URL in .gitshiprc.json:
{
"jira": {
"baseUrl": "https://yourcompany.atlassian.net",
"projectKey": "PROJ"
}
}Asana (Experimental)
Requires your Asana personal access token:
export ASANA_ACCESS_TOKEN="your-access-token"
gs config set issueTracker.provider asanaNote: Asana uses numeric task GIDs. Include the GID in your branch name (e.g., feat/1234567890123-task-name).
Plain Text
Enter requirements manually each time you commit:
gs config set issueTracker.provider plainWhen you run gs, you'll be prompted:
? Would you like to provide context/requirements for these changes? Yes
? Enter the requirements or context for these changes: Add user authentication with OAuth2None
Skip issue context entirely. Commits will be based on diffs only.
Warning: Without context, commit messages will be generic:
feat(src): feat changes in src
chore(root): chore changes in rootWith context, you get meaningful messages:
feat(auth): add OAuth2 login with Google provider
fix(cart): resolve race condition in quantity updateCommit Message Structure
git-ship generates rich, structured commit messages with three distinct sections:
┌──────────────────────────────────────────────────────────────┐
│ feat(auth): add OAuth2 login with Google provider │ ← Header (limited length)
│ │
│ Implement Google OAuth2 authentication: │
│ - Add OAuth2 callback handler │ ← Body (detailed, no limit)
│ - Store tokens securely in session │
│ - Add logout endpoint to revoke tokens │
│ │
│ Addresses: "Users should be able to log in with Google" │ ← Footer (requirement mapping)
│ Refs: ENG-123 │
└──────────────────────────────────────────────────────────────┘Header
The first line of the commit, shown in git log --oneline and PR merge lists. Limited to your configured maxMessageLength (default: 72 characters). The length budget accounts for the type(scope): prefix — if feat(auth): takes 12 characters, the summary gets the remaining 60. Summaries that exceed the limit are automatically truncated with ....
Body
A detailed explanation of what changed and why. The body has no length limit — write as much context as needed. Lines are automatically word-wrapped at 72 characters for readability in terminals and git log, preserving bullet-point indentation. The AI generates the body for any non-trivial change; trivial changes (typo fixes, formatting) skip it.
Footer
The footer maps commits back to requirements and issue references:
Addresses:— Quotes or paraphrases the specific requirement this commit fulfills. Only present when issue context or plain-text requirements are provided. Helps reviewers understand why a change was made without switching to the issue tracker.Refs:— The issue ID (e.g.,Refs: ENG-123). Only present whencommits.includeIssueRefistrueand an issue ID was detected or provided.
The footer is separated from the body by a blank line, following the Conventional Commits trailer format.
Branch Parsing
git-ship detects issue IDs from branch names with flexible matching:
| Branch Name | Detected Issue | Confidence |
| ---------------------------------- | -------------- | ---------- |
| feat/ENG-123-user-auth | ENG-123 | High |
| fix/eng-456 | ENG-456 | High |
| feat/oxford-optimisation-elm-123 | ELM-123 | High* |
| mayank/DES-789-design-update | DES-789 | High |
| feature-abc-123-description | ABC-123 | Medium** |
*If ELM is in your configured team prefixes
**Medium confidence prompts for confirmation
Configure team prefixes during setup or in config:
{
"branch": {
"teamPrefixes": ["ENG", "DES", "ELM", "PROD"]
}
}Commit Grouping
Files are grouped using a two-pass approach that balances two goals: small, reviewer-friendly commits and safe revertability. Every commit should be easy to review in isolation and safe to revert without breaking the build.
Pass 1 — Heuristic pre-grouping
A fast first pass groups files by path patterns:
| Pattern | Category |
| ------------------------- | -------------------- |
| *.test.ts, tests/ | test |
| *.md, docs/ | docs |
| Dockerfile, .github/ | ci-infra |
| package.json, lockfiles | deps |
| migrations/ | migration |
| Source files | Grouped by directory |
Pass 2 — AI refinement
The AI analyzes your changes and applies two tests:
- The Revert Test (safety floor) — "If this commit were reverted, would the codebase still compile and run?" Files that depend on each other must stay together.
- The Review Test (quality goal) — "Can a reviewer understand this commit without reading the others?" Prefer smaller, focused commits that each tell one clear story.
When issue context is available (from Linear, Jira, Asana, or plain text), the AI uses it to better understand the intent of your changes and map commits to specific requirements.
Optimized for large changesets: Instead of sending full diffs to the AI (which can cause truncation with many files), git-ship sends compressed summaries — changed symbols, imports, and exports — giving the AI everything it needs to group files in a fraction of the tokens. Lockfile diffs are skipped entirely (they always group with their manifest). Only ambiguous source files include a short diff excerpt.
AI Failure Handling
If the AI call fails (e.g., API quota exceeded, rate limit, invalid key, response truncation), git-ship:
- Shows a clear, user-friendly error message explaining what went wrong
- Displays a context-specific suggestion for fixing the issue
- Lets you choose: Continue with basic commits, Retry, or Cancel
✖ AI commit analysis failed
✖ API quota or rate limit exceeded (openai/gpt-4o)
Suggestion: Check your OPENAI_API_KEY or ANTHROPIC_API_KEY env var.
? How would you like to proceed?
❯ Continue with basic commits (generic messages)
Retry AI analysis
CancelFor response truncation (too many files for the AI to process):
✖ AI commit analysis failed
✖ The AI could not finish analyzing all your files — its response was cut off.
Suggestion: Stage fewer files and commit in smaller batches,
or choose "Continue with basic commits" to skip AI grouping.Fallback
If AI is unavailable or you choose to continue without it, heuristic groups from Pass 1 are used directly with auto-generated conventional commit messages.
Ignore Patterns
git-ship automatically filters out files that should never be committed. The default ignore patterns are:
{
"ignorePatterns": [
"node_modules/**",
".env*",
"dist/**",
".DS_Store"
]
}You can customize this list in your .gitshiprc.json to exclude additional files:
{
"ignorePatterns": [
"node_modules/**",
".env*",
"dist/**",
".DS_Store",
"coverage/**",
"*.generated.ts",
".gitshiprc.json"
]
}Supported Pattern Syntax
| Pattern | Matches | Example |
| -------------- | --------------------------------------------------- | ------------------------------- |
| dir/** | Any path under that directory | dist/** matches dist/main.js |
| prefix* | Any filename starting with prefix | .env* matches .env.local |
| exact | Exact match against full path or basename | .DS_Store matches anywhere |
Files matching any ignore pattern are silently excluded before the file picker and AI analysis — they never appear in the workflow.
Interactive File Selection
After collecting changed files, git-ship presents an interactive checkbox picker so you can choose exactly which files to include in this commit session:
? Select files to include:
◉ M src/api/routes.ts
◉ M src/services/auth.ts
◯ M vite.config.ts
◉ A src/utils/helpers.tsAll files are checked by default. Deselect any files you want to skip — they remain as uncommitted changes in your working tree.
Use cases:
- Skip local config changes — Deselect
vite.config.ts,.eslintrc, or other local tweaks you never intend to commit - Cherry-pick files across branches — When multiple developers or agents are editing the same repo, select only the files relevant to your current task
- Incremental commits — Commit part of a large changeset now, come back for the rest later
The picker appears after ignore-pattern filtering, so you only see files that are eligible for committing. If you deselect everything, git-ship exits with "No files selected."
Code Review
| Tool | Status | Notes |
| ---------- | ------------ | ------------------------------------------------------------------ |
| Graphite | Recommended | Uses gt CLI — install with npm i -g @withgraphite/graphite-cli |
| CodeRabbit | Experimental | Requires CLI or API key |
| Codex | Experimental | Uses your OPENAI_API_KEY |
| Devin | Experimental | Limited access, invite-only |
Findings are normalized with severity levels (critical, warning, info). Critical findings block the push by default.
Pull Request Creation
After pushing, git-ship can create a pull request with an AI-generated description that follows industry standards.
Automatic PR (after push)
At the end of the gs workflow, you'll be prompted:
? Create a pull request? Yes
? PR title: feat(auth): add OAuth2 authentication
✓ Generating PR description with AI
? Edit PR description before creating? No
? Create as draft PR? No
✓ Pull request created: https://github.com/user/repo/pull/123Standalone PR Command
Create a PR anytime for your current branch:
gs pr # Interactive PR creation
gs pr --draft # Create as draft
gs pr --title "My PR" # Set title directly
gs pr --base develop # Target a different base branchAI-Generated PR Description
The PR description is generated using your configured AI provider and includes:
## Summary
Brief 2-3 sentence overview of what this PR does and why.
## Problem
What problem, issue, or requirement does this PR address?
## Solution
How does this PR solve the problem? High-level approach.
## Changes Made
- Key changes organized logically (not just a commit dump)
- Grouped by feature or component
## Impact
What parts of the system are affected? Breaking changes?
## Testing
How was this tested? What should reviewers verify?
## Additional Context
Any other information reviewers should know.GitHub CLI (Optional)
For automatic PR creation:
- GitHub CLI (
gh) must be installed:brew install gh - Visit https://cli.github.com/ for other operating systems
- Must be authenticated:
gh auth login
If gh is not available, git-ship will still generate the PR description and display it for you to copy-paste when creating the PR manually on GitHub.
Configuration
Global Configuration
Stored at ~/.config/gitship/config.json. Created automatically by the setup wizard. Works across all repos.
gs --setup # Re-run setup wizard anytime
gs config # View current settingsAPI Key Storage
API keys are stored in your shell profile for security and persistence:
| Shell | Profile Location |
| ----- | ---------------------------- |
| zsh | ~/.zshrc |
| bash | ~/.bashrc |
| fish | ~/.config/fish/config.fish |
The setup wizard automatically detects your shell and adds keys in the correct format. If a key already exists, you'll be asked whether to use the existing key or update it.
After adding new keys, run source ~/.zshrc (or your shell's profile) to use them in the current terminal session.
Per-Repository Setup
The first time you run git-ship in a new repository, you'll see:
First time using git-ship in this repository.
? How would you like to configure this repository?
> Use global config (recommended)
Customize for this repo
Skip for now- Use global config — Creates a minimal
.gitshiprc.jsonthat references your global settings. The prompt won't appear again. - Customize for this repo — Launches a wizard to override specific settings (AI provider, review tool, commit length, etc.)
- Skip for now — Uses global config for this run, but you'll be prompted again next time.
Local Configuration (per-repo)
Create a .gitshiprc.json in your project root to override global settings:
{
"issueTracker": {
"provider": "linear"
},
"ai": {
"provider": "openai",
"model": "gpt-4o"
},
"linear": {
"transport": "graphql"
},
"jira": {
"baseUrl": "https://yourcompany.atlassian.net",
"projectKey": "ENG"
},
"review": {
"enabled": true,
"tool": "graphite",
"transport": "cli"
},
"commits": {
"conventional": true,
"allowedTypes": [
"feat",
"fix",
"chore",
"docs",
"refactor",
"test",
"ci",
"build",
"perf"
],
"includeIssueRef": true,
"maxMessageLength": 72
},
"ignorePatterns": [
"node_modules/**",
".env*",
"dist/**",
".DS_Store",
".gitshiprc.json"
],
"branch": {
"teamPrefixes": ["ENG", "DES"]
}
}Config Precedence
CLI flags (--review-tool, --issue, etc.)
↓
Environment variables (GITSHIP_*)
↓
Local config (.gitshiprc.json)
↓
Global config (~/.config/gitship/config.json)
↓
DefaultsEnvironment Variables
git-ship loads .env from your project root automatically.
API keys:
| Variable | Description |
| -------------------- | ----------------------------------------------------- |
| LINEAR_API_KEY | Linear workspace API key |
| OPENAI_API_KEY | OpenAI API key |
| ANTHROPIC_API_KEY | Anthropic API key |
| GEMINI_API_KEY | Google Gemini API key (also accepts GOOGLE_API_KEY) |
| JIRA_API_TOKEN | Jira API token |
| JIRA_EMAIL | Jira account email |
| ASANA_ACCESS_TOKEN | Asana personal access token |
| CODERABBIT_API_KEY | CodeRabbit API key (optional) |
| DEVIN_API_KEY | Devin API key (optional) |
Config overrides:
| Variable | Values |
| ----------------------------- | ------------------------------------------------------------ |
| GITSHIP_AI_PROVIDER | openai, anthropic, gemini |
| GITSHIP_AI_MODEL | Any model string (e.g. gpt-4o, claude-sonnet-4-20250514) |
| GITSHIP_LINEAR_TRANSPORT | graphql, mcp |
| GITSHIP_REVIEW_TOOL | coderabbit, devin, codex, graphite |
| GITSHIP_REVIEW_ENABLED | true, false |
| GITSHIP_REVIEW_TRANSPORT | mcp, cli |
| GITSHIP_COMMIT_MAX_LENGTH | 20 – 200 |
| GITSHIP_DEVIN_ENDPOINT | Custom MCP endpoint for Devin |
| GITSHIP_CODERABBIT_ENDPOINT | Custom MCP endpoint for CodeRabbit |
| GITSHIP_CODEX_ENDPOINT | Custom MCP endpoint for Codex |
Graceful Degradation
git-ship is designed to work even when things fail:
| Failure | Behavior | | ------------------- | ----------------------------------------- | | Issue tracker fails | Warns, proceeds without issue context | | AI provider fails | Shows error, offers retry/continue/cancel | | Review tool missing | Warns, offers to skip | | Push rejected | Shows error with suggested fix | | No changes | Clean exit with info message |
Requirements
- Node.js >= 18
- Git
License
MIT
