urur

Crates.iourur
lib.rsurur
version0.2.44
created_at2026-01-04 22:02:44.155671+00
updated_at2026-01-22 13:25:31.272501+00
descriptionMulti-repo workspace manager - manage distributed Git repositories with a single config
homepagehttps://github.com/rusenbb/urur
repositoryhttps://github.com/rusenbb/urur
max_upload_size
id2022595
size1,266,599
Rusen Birben (rusenbb)

documentation

README

urur

A multi-repo workspace manager for developers who work across many distributed Git repositories.

Crates.io License: MIT

Why urur?

If you work with multiple Git repositories spread across GitHub, GitLab, and other hosts, you know the pain of:

  • Cloning repos one by one
  • Checking status of 10+ repos manually
  • Running the same command in each repo
  • Remembering which repos need to be pulled

urur solves this with a single configuration file that manages all your repositories.

# Clone all your repos
urur clone

# Check status everywhere
urur status

# Pull everything
urur pull

# Run any command across repos
urur exec "git log -1 --oneline"

Installation

From crates.io

cargo install urur

From source

git clone https://github.com/rusenbb/urur.git
cd urur
cargo install --path .

Pre-built binaries

Download from the releases page.

Quick Start

# 1. Initialize a workspace
mkdir my-repos && cd my-repos
urur init --name "my-workspace"

# 2. Add repositories
urur add https://github.com/user/repo1.git --tag work
urur add git@github.com:user/repo2.git --tag personal

# 3. Clone everything
urur clone

# 4. Check status
urur status

Configuration

urur uses a .urur.toml file for configuration:

[workspace]
name = "my-workspace"
description = "All my projects"

[defaults]
branch = "main"
shallow = false
parallel = 4
editor = "code"  # Editor for 'open' command (code, nvim, zed, etc.)

[[repos]]
name = "project-a"
url = "git@github.com:user/project-a.git"
path = "work/project-a"      # Custom directory structure
branch = "develop"           # Override default branch
tags = ["work", "rust"]

[[repos]]
name = "project-b"
url = "git@github.com:user/project-b.git"
path = "personal/project-b"
tags = ["personal", "python"]

[groups]
work = ["project-a"]
all-rust = ["project-a"]

Repository Options

Field Description Default
name Unique identifier Derived from URL
url Git clone URL (HTTPS or SSH) Required
path Local directory path Same as name
branch Default branch From defaults.branch
tags Tags for filtering []
shallow Shallow clone false
disabled Skip this repo false

Commands

Workspace Management

urur init [--name NAME]     # Initialize a new workspace
urur list [--json]          # List all repositories
urur doctor                 # Health check for your workspace

Repository Operations

# Add/remove repos
urur add <url> [--name NAME] [--path PATH] [--branch BRANCH] [--tag TAG...] [--clone]
urur remove <name> [--delete]   # --delete removes local files too

# Clone
urur clone                      # Clone all repos
urur clone repo1 repo2          # Clone specific repos
urur clone --group work         # Clone repos in a group
urur clone --tag rust           # Clone repos with a tag

Status and Sync

urur status                     # Show all repo statuses
urur status --dirty             # Show only dirty repos
urur dirty                      # List repos with uncommitted changes
urur behind                     # List repos behind remote
urur diff                       # Show diff summary across repos

Git Operations

urur pull [--group GROUP] [--tag TAG]      # Pull all repos
urur fetch [--group GROUP]                  # Fetch all repos
urur fetch-upstream [--group GROUP]         # Fetch from upstream for forked repos
urur push [--group GROUP] [--tag TAG]      # Push all repos
urur checkout <branch>                      # Checkout branch across repos
urur sync                                   # Smart sync: stash, fetch, rebase, unstash
urur gc                                     # Run git gc in all repos

Stash and Branch

# Stash operations
urur stash                      # Stash in all repos
urur stash push                 # Same as above
urur stash pop                  # Pop stash in all repos
urur stash list                 # List stashes in all repos

# Branch operations
urur branch list                # Show current branch in all repos
urur branch create <name>       # Create branch in all repos
urur branch delete <name>       # Delete branch in all repos

Execute Commands

urur exec <command>                         # Run in all repos
urur exec "npm install" --tag nodejs        # Run in tagged repos
urur exec "cargo test" --group rust-projects

Group Management

urur group list                             # List all groups
urur group create <name> [repos...]         # Create a group
urur group add <name> <repo>                # Add repo to group
urur group remove <name> <repo>             # Remove repo from group
urur group delete <name>                    # Delete a group

Remote Management

urur remote list [repo]                     # List remotes for repo(s)
urur remote add <repo> <name> <url>         # Add a remote (e.g., upstream)
urur remote remove <repo> <name>            # Remove a remote

Move and Import

# Move a repository to a new path
urur move <name> <new-path> [--force]

# Import existing git repos from a directory
urur import [path] [--recursive] [--tag TAG] [--dry-run]

Select Mode

Focus on a single repository and use urur as a git alias:

# Select a repo (and optionally cd into it)
urur select project-a
# Or with automatic cd:
eval "$(urur select project-a --cd)"

# Now urur commands run on that repo
urur status          # git status in project-a
urur log             # git log in project-a
urur commit -m "..."  # git commit in project-a

# Open in editor or browser
urur open            # Opens in $EDITOR or 'code'
urur web             # Opens remote URL in browser

# See what's selected
urur which

# Back to multi-repo mode (and optionally cd to workspace)
urur unselect
# Or with automatic cd:
eval "$(urur unselect --cd)"

Shell Integration

For seamless cd on select/unselect, add to your .bashrc or .zshrc:

# Shell wrapper for urur select/unselect with automatic cd
urur() {
    case "$1" in
        select)
            shift
            eval "$(command urur select "$@" --cd)"
            ;;
        unselect)
            eval "$(command urur unselect --cd)"
            ;;
        *)
            command urur "$@"
            ;;
    esac
}

# Alternative: simple cd helper
ucd() {
    cd "$(urur cd)"
}

Shell Completions

Generate shell completions:

# Bash
urur completions bash > ~/.local/share/bash-completion/completions/urur

# Zsh
urur completions zsh > ~/.zfunc/_urur

# Fish
urur completions fish > ~/.config/fish/completions/urur.fish

# PowerShell
urur completions powershell > ~\Documents\PowerShell\Modules\urur\urur.ps1

Examples

Organize by Project Type

[[repos]]
name = "frontend"
url = "git@github.com:company/frontend.git"
path = "web/frontend"
tags = ["web", "typescript"]

[[repos]]
name = "backend"
url = "git@github.com:company/backend.git"
path = "api/backend"
tags = ["api", "rust"]

[[repos]]
name = "mobile"
url = "git@github.com:company/mobile.git"
path = "mobile/app"
tags = ["mobile", "react-native"]

Work vs Personal

[groups]
work = ["frontend", "backend", "mobile"]
personal = ["dotfiles", "blog", "side-project"]

# Pull only work repos
# urur pull --group work

# Status of personal projects
# urur status --group personal

Microservices

[[repos]]
name = "auth-service"
url = "git@github.com:company/auth-service.git"
tags = ["service", "critical"]

[[repos]]
name = "user-service"
url = "git@github.com:company/user-service.git"
tags = ["service"]

[[repos]]
name = "payment-service"
url = "git@github.com:company/payment-service.git"
tags = ["service", "critical"]

# Run tests on all services
# urur exec "make test" --tag service

# Check critical services
# urur status --tag critical

Comparison with Other Tools

Feature urur git-repo gita myrepos
Config format TOML XML YAML Config file
Tags/Groups Yes Yes (projects) Yes No
Custom paths Yes Limited No Yes
Select mode Yes No No No
Interactive TUI Yes No No No
Cloud sync Yes No No No
Worktrees Yes No No No
Shell completions Yes Yes Yes No
Written in Rust Python Python Perl

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

New Features

Interactive TUI

Launch an interactive dashboard to view and manage all repositories:

urur tui

TUI Features:

  • Tree or list view of all repos (t to toggle)
  • Real-time status (branch, dirty, ahead/behind)
  • Bulk operations on selected repos
  • Add repos directly (a key)
  • Import from GitHub/GitLab (i key)
  • Move and rename repos (m, R keys)
  • Search/filter repos (/ key)
  • Comprehensive help (? key)

Cloud Sync

Sync your workspace config to a git repository (like your dotfiles):

# Initialize cloud sync
urur cloud init git@github.com:user/dotfiles.git

# Push config changes to cloud
urur cloud push

# Pull config from cloud
urur cloud pull

# Check sync status
urur cloud status

# Unlink cloud sync
urur cloud unlink

Worktree Management

Manage git worktrees across your repositories:

# Add a worktree for a feature branch
urur worktree add my-repo feature-branch

# List worktrees
urur worktree list my-repo

# Remove a worktree
urur worktree remove my-repo feature-branch

Import from GitHub/GitLab

Bulk import repositories from your GitHub or GitLab account:

# Import all your GitHub repos
urur import-github myusername

# Import private repos too (requires GITHUB_TOKEN)
urur import-github myusername --private

# Filter by language
urur import-github myusername --language rust

# Import from GitLab
urur import-gitlab myusername

Configurable Editor

Set your preferred editor in the config:

[defaults]
editor = "nvim"  # or "code", "zed", "vim", etc.

Priority: CLI arg > config > $EDITOR > $VISUAL > "code"

Repository Templates

Define templates to quickly add repos with pre-configured settings:

[templates.rust]
shallow = true
tags = ["rust", "backend"]
path_prefix = "libs/"
post_clone = "cargo build"
groups = ["backend"]

[templates.node]
tags = ["javascript", "frontend"]
path_prefix = "web/"
post_clone = "npm install"

Use templates when adding repos:

# Add with template
urur add https://github.com/user/my-lib.git --template rust

# List available templates
urur template list

# Show template details
urur template show rust

Template settings (explicit CLI args override template values):

  • branch: Default branch to checkout
  • shallow: Whether to shallow clone
  • tags: Tags to apply automatically
  • path_prefix: Prefix for the local path (e.g., "libs/" → "libs/repo-name")
  • post_clone: Command to run after cloning
  • groups: Groups to automatically add the repo to

Hooks

Run custom commands before/after operations:

[hooks]
strict = true  # Abort on pre-hook failure

# Clone hooks
pre_clone = "echo 'Starting clone...'"
post_clone = "npm install"

# Pull hooks
pre_pull = "git stash"
post_pull = "git stash pop"

# Fetch hooks
pre_fetch = "echo 'Fetching...'"
post_fetch = "echo 'Fetch complete'"

# Sync hooks (for `urur sync` command)
pre_sync = "echo 'Starting sync...'"
post_sync = "echo 'Sync complete'"

Environment variables available in hooks:

  • URUR_REPO_NAME - Repository name
  • URUR_REPO_PATH - Repository local path
  • URUR_REPO_URL - Repository remote URL
  • URUR_WORKSPACE_ROOT - Workspace root directory

Search Across Repos

Search for patterns across all repositories:

urur search "TODO"
urur search "function.*Error" --glob "*.ts"

Roadmap

  • Core workspace management
  • Group and tag filtering
  • Select mode for single-repo focus
  • Shell completions
  • Progress bars during operations
  • Interactive TUI mode
  • GitHub/GitLab import
  • Hooks system
  • Search across repos
  • Parallel operations
  • Cloud config sync
  • Worktree management
  • Configurable editor
  • TUI add/import modals
  • Repository templates
  • Stable repo identity (UUID-based tracking for moves/renames)
  • Cloud sync reconciliation (detect moves/deletes across machines)
  • urur reconcile command
  • Workspace snapshots
  • Plugin system

See the backlog for future plans.

Commit count: 190

cargo fmt