Manage multiple related repositories as a single workspace with synchronized branches, linked pull requests, and atomic merges.
Inspired by Android's repo tool, gitgrip brings manifest-based multi-repo management to any project.
Features
- Manifest-based configuration - Define all your repos in a single YAML file
- Multi-platform support - Works with GitHub, GitLab, and Azure DevOps (even mixed in one workspace)
- Synchronized branches - Create and checkout branches across all repos at once
- Linked PRs - Create pull requests that reference each other across repos
- Atomic merges - All-or-nothing merge strategy ensures repos stay in sync
- Status dashboard - See the state of all repos at a glance
Installation
Homebrew (macOS/Linux)
From crates.io
From GitHub Releases
Pre-built binaries for Linux, macOS (Intel & Apple Silicon), and Windows are available on the releases page.
From Source
# Binary is at target/release/gr (or gr.exe on Windows)
# Install to ~/.cargo/bin:
Quick Start
1. Create a manifest repository
Create a new repo to hold your workspace manifest (e.g., my-workspace), then add a manifest.yaml:
version: 1
manifest:
url: git@github.com:your-org/my-workspace.git
repos:
frontend:
url: git@github.com:your-org/frontend.git
path: ./frontend
default_branch: main
backend:
url: git@github.com:your-org/backend.git
path: ./backend
default_branch: main
shared:
url: git@github.com:your-org/shared-libs.git
path: ./shared
default_branch: main
settings:
pr_prefix: "[cross-repo]"
merge_strategy: all-or-nothing
2. Initialize a workspace
From a manifest URL:
From existing local directories:
# Auto-scan current directory for git repos
# Scan specific directories
# Interactive mode - preview and edit manifest before saving
This creates .gitgrip/manifests/ with the manifest configuration.
3. Start working
# Check status of all repos
# Create a feature branch across all repos
# Make changes, commit in each repo, then create linked PRs
# Sync all repos with latest from remote
Commands
| Command | Description |
|---|---|
gr init <url> |
Initialize workspace from manifest repo |
gr init --from-dirs |
Initialize workspace from existing local directories |
gr sync |
Pull latest from all repos |
gr status |
Show status of all repos |
gr branch [name] |
Create or list branches |
gr checkout <branch> |
Checkout branch across repos |
gr add [files] |
Stage changes across repos |
gr diff |
Show diff across repos |
gr commit -m "msg" |
Commit across repos |
gr push |
Push across repos |
gr pr create |
Create linked PRs |
gr pr status |
Show PR status |
gr pr merge |
Merge all linked PRs |
gr pr checks |
Show CI check status |
gr pr diff |
Show PR diff |
gr repo add <url> |
Add a new repository to workspace |
gr repo list |
List all repositories |
gr repo remove <name> |
Remove a repository |
gr forall -c "cmd" |
Run command in each repo |
gr tree add <branch> |
Create a worktree-based workspace |
gr tree list |
List all griptrees |
gr tree remove <branch> |
Remove a griptree |
gr rebase |
Rebase across repos |
gr link |
Manage file links |
gr run <script> |
Run workspace scripts |
gr env |
Show environment variables |
gr bench |
Run performance benchmarks |
gr completions <shell> |
Generate shell completions |
Command Details
gr init <manifest-url>
Initialize a new workspace by cloning the manifest repository and all defined repos.
gr init --from-dirs
Initialize a workspace from existing local git repositories. Discovers repos, extracts remote URLs and default branches, and generates a manifest.
| Option | Description |
|---|---|
--from-dirs |
Create workspace from existing directories |
--dirs <paths> |
Specific directories to scan (default: all subdirs) |
-i, --interactive |
Preview manifest and confirm before writing |
Features:
- Auto-detects remote URLs and default branches
- Handles duplicate directory names with auto-suffixing
- Initializes manifest as a git repository with initial commit
- In interactive mode, edit the generated YAML before saving
gr sync [options]
Pull latest changes from the manifest and all repositories.
| Option | Description |
|---|---|
--fetch |
Fetch only, don't merge |
--no-link |
Skip processing copyfile/linkfile entries |
--no-hooks |
Skip running post-sync hooks |
gr status
Show status of all repositories including branch, changes, and sync state.
gr branch [name]
Create a new branch across all repositories, or list existing branches.
| Option | Description |
|---|---|
-r, --repo <repos...> |
Only operate on specific repos |
--include-manifest |
Include manifest repo |
gr pr create
Create linked PRs across repos with changes.
| Option | Description |
|---|---|
-t, --title <title> |
PR title |
-b, --body <body> |
PR body |
-d, --draft |
Create as draft |
--push |
Push branches first |
gr pr merge
Merge all linked PRs atomically.
| Option | Description |
|---|---|
-m, --method <method> |
merge, squash, or rebase |
-f, --force |
Merge even if checks pending |
-u, --update |
Update branch from base if behind, then retry merge |
--auto |
Enable auto-merge (merges when all checks pass) |
gr repo add <url>
Add a new repository to the workspace. Parses the URL, updates the manifest, and optionally clones the repo.
| Option | Description |
|---|---|
--path <path> |
Local path (default: ./<repo-name>) |
--name <name> |
Name in manifest (default: from URL) |
--branch <branch> |
Default branch (default: main) |
--no-clone |
Only update manifest, skip cloning |
If the workspace is on a feature branch, the new repo will be checked out to that branch automatically.
gr forall -c "<command>"
Run a command in each repository (like AOSP's repo forall).
| Option | Description |
|---|---|
-c, --command |
Command to run (required) |
-r, --repo <repos...> |
Only run in specific repos |
--include-manifest |
Include manifest repo |
--continue-on-error |
Continue if command fails |
Environment variables available in command:
REPO_NAME- Repository nameREPO_PATH- Absolute path to repoREPO_URL- Repository URL
Manifest Format
The manifest file (manifest.yaml) defines your workspace:
version: 1
manifest:
url: git@github.com:your-org/workspace.git
repos:
repo-name:
url: git@github.com:your-org/repo.git
path: ./local-path
default_branch: main
settings:
pr_prefix: "[cross-repo]"
merge_strategy: all-or-nothing
Merge Strategies
- all-or-nothing - All linked PRs must be approved before any can merge
- independent - PRs can be merged independently
Multi-Platform Support
gitgrip supports multiple hosting platforms. The platform is auto-detected from the repository URL.
Supported Platforms
| Platform | URL Patterns |
|---|---|
| GitHub | git@github.com:org/repo.git, https://github.com/org/repo.git |
| GitLab | git@gitlab.com:group/repo.git, https://gitlab.com/group/repo.git |
| Azure DevOps | git@ssh.dev.azure.com:v3/org/project/repo, https://dev.azure.com/org/project/_git/repo |
Authentication
Each platform requires its own authentication:
GitHub:
# or
GitLab:
# or
Azure DevOps:
# or
Mixed-Platform Workspaces
A single manifest can contain repos from different platforms:
repos:
frontend:
url: git@github.com:org/frontend.git
path: ./frontend
backend:
url: git@gitlab.com:org/backend.git
path: ./backend
infra:
url: https://dev.azure.com/org/project/_git/infra
path: ./infra
Self-Hosted Instances
For GitHub Enterprise, GitLab self-hosted, or Azure DevOps Server, add a platform config:
repos:
internal:
url: git@gitlab.company.com:team/repo.git
path: ./internal
platform:
type: gitlab
baseUrl: https://gitlab.company.com
Griptrees (Multi-Branch Workspaces)
Work on multiple branches simultaneously without switching. Griptrees use git worktrees to create parallel workspace directories.
# Create a griptree for a feature branch
# Creates a sibling directory with all repos on that branch:
# ../feat-new-feature/
# ├── frontend/
# ├── backend/
# └── shared/
# Work in the griptree
# List all griptrees
# Lock to prevent accidental removal
# Remove when done (branches are preserved)
Benefits:
- No branch switching required
- Shared git objects (fast creation, minimal disk usage)
- Independent working directories
Shorthand
Use gr as the primary command:
The long form gitgrip also works.
Shell Completions
Generate shell completions for tab completion:
# Bash
# Or add to ~/.bashrc:
# Zsh
# Or add to ~/.zshrc:
# Fish
# PowerShell
Supported shells: bash, zsh, fish, elvish, powershell
Requirements
- Git
- Platform CLI (optional, for token auth fallback):
- GitHub:
ghCLI - GitLab:
glabCLI - Azure DevOps:
azCLI
- GitHub:
History
This project was originally written in TypeScript and published to npm as gitgrip. It was rewritten in Rust for better performance and additional features.
License
MIT