A read-only Git repository manager for exploration and reference. Keep a tidy collection of cloned repos you want to study, search, or reference—without the overhead of managing them manually.
When exploring codebases for learning or reference, you often end up with repos scattered across your filesystem. clones gives you:
- One location (
~/Clones) for all reference repositories - A registry tracking metadata, tags, and sync status
- Fast clones using shallow + single-branch by default
- Easy sync to keep everything up-to-date
- Interactive browser with type-ahead search
npm install -g clones-cliRequires Node.js 18+.
# Add a repository
clones add https://github.com/unjs/citty
# Browse interactively
clones
# List all repos
clones list
# Sync everything (fetch updates, adopt new repos, clone missing)
clones syncOpens the interactive browser with type-ahead search. Filter by name or tags, view details, copy paths, edit metadata.
Clone a repository to ~/Clones/<owner>/<repo>.
clones add https://github.com/owner/repo
clones add git@github.com:owner/repo.git
# With metadata
clones add https://github.com/owner/repo --tags "cli,typescript" --description "My notes"
# Clone full history (default is shallow)
clones add https://github.com/owner/repo --full
# Clone all branches (default is single branch)
clones add https://github.com/owner/repo --all-branchesURL normalization: GitHub web UI URLs work too—/tree/main, /blob/main/file.ts, etc. are stripped automatically.
Metadata: For GitHub repos, description and topics are fetched automatically.
Show all tracked repositories with status.
clones list # Pretty output
clones list --json # JSON output
clones list --filter "unjs/*" # Filter by pattern
clones list --tags cli,typescript # Filter by tagsSynchronize registry with filesystem:
- Adopt untracked repos found in
~/Clones - Clone repos in registry that are missing from disk
- Fetch and reset existing repos to upstream
clones sync # Sync all
clones sync --filter "unjs/*" # Sync matching repos only
clones sync --dry-run # Preview changes
clones sync --force # Sync even if working tree is dirty
clones sync --keep # Keep tombstoned repos on disk
clones sync --refresh # Re-fetch metadata from GitHub
clones sync --concurrency 6 # Parallel git operations (default: 4, max: 10)You can cancel long-running sync operations with Esc or Ctrl+C. Cancellation stops
new work from starting but allows in-flight git operations to finish safely.
Update strategies (per-repo, set on add):
hard-reset(default): Reset to upstream, discarding local changesff-only: Fast-forward only, fail if diverged
Normalize and validate config files (registry.toml and local.json), dropping unknown fields and repairing invalid values.
clones doctorRemove a repository from the registry.
clones rm owner/repo # Remove from registry, keep files
clones rm owner/repo --purge # Remove from registry AND delete files
clones rm owner/repo --yes # Skip confirmation~/Clones/
├── owner1/
│ ├── repo1/
│ └── repo2/
├── owner2/
│ └── repo3/
Config files live in ~/.config/clones/:
~/.config/clones/
├── registry.toml # Shared registry (sync to dotfiles)
└── local.json # Machine-local state
The registry tracks:
- Clone URL and host
- Description and tags
- Update strategy and sync timestamps
- Submodule and LFS preferences
- Tombstones (repo IDs that should be removed from disk if found)
Local state tracks:
- Last sync run and per-repo last synced timestamps (machine-only)
You can customize paths via environment variables:
export CLONES_CONTENT_DIR="$HOME/Clones" # default
export CLONES_CONFIG_DIR="$HOME/.config/clones"
export CLONES_SYNC_CONCURRENCY="4" # default sync workersCLONES_CONFIG_DIR overrides XDG_CONFIG_HOME for config location. CLONES_CONTENT_DIR is the root directory where repositories are cloned.
CLONES_DIR is deprecated but still supported as a fallback for CLONES_CONTENT_DIR.
You can also set a default concurrency in ~/.config/clones/config.json:
{
"sync": {
"concurrency": 4
}
}By default, clones are:
- Shallow (
--depth 1): Only the latest commit - Single-branch: Only the default branch
This makes cloning fast—even multi-GB repos clone in seconds. Use --full and --all-branches if you need history or other branches.
To expand a shallow clone later:
cd ~/Clones/owner/repo
git fetch --unshallowFailed operations roll back cleanly:
- If a clone fails, created directories are removed
- The registry only updates after successful operations
- No partial state left behind
MIT