Rust CLI to clone a GitHub/GitLab (or other Git) repo to ~/Projects while keeping a tree
structure close to the remote URL. If the project already exists locally the CLI can
be used to print commands for updating or changing directory instead of cloning.
Organizing cloned repositories consistently is tedious. git-mirror automates this by:
- Smart directory structure - Mirrors the remote URL structure locally (
~/Projects/github/owner/repo) - Works with any Git host - GitHub, GitLab, Bitbucket, or self-hosted instances
- Shell integration - Print
cdcommands to jump straight into cloned repos - VS Code ready - Optionally open repos in VS Code immediately after cloning
- Fast and lightweight - Written in Rust for maximum performance
Install via the automated installation script:
curl -fsSL https://raw.githubusercontent.com/thoroc/git-mirror/main/install.sh | bashThis will:
- Detect your OS and architecture automatically
- Download the latest release binary
- Verify the checksum for security
- Install to
~/.local/bin/git-mirror(or custom location viaINSTALL_DIRenv var)
Custom installation directory:
curl -fsSL https://raw.githubusercontent.com/thoroc/git-mirror/main/install.sh | INSTALL_DIR=/usr/local/bin bashDownload the appropriate binary for your system from the latest release:
- Linux x86_64:
git-mirror-linux-x86_64.tar.gz - Linux ARM64:
git-mirror-linux-aarch64.tar.gz - macOS Intel:
git-mirror-macos-x86_64.tar.gz - macOS Apple Silicon:
git-mirror-macos-aarch64.tar.gz - Windows:
git-mirror-windows-x86_64.zip
Extract and move to a directory in your PATH:
# Linux/macOS example
tar -xzf git-mirror-*.tar.gz
mv git-mirror ~/.local/bin/
chmod +x ~/.local/bin/git-mirrorBuild and install locally with Cargo:
cargo install --path .This installs a git-mirror binary in your Cargo bin directory (usually ~/.cargo/bin).
Alternatively during development run via:
cargo run -- <repo> --print-cdTo add a Git alias for convenience, add to your ~/.gitconfig:
[alias]
mirror = "!git-mirror"After installing, you can call git-mirror directly (or git mirror if you set the alias).
gitinstalled and available on yourPATH.- Rust toolchain (
rustcandcargo) if you want to build from source. - SSH keys configured for SSH-style remotes (if using
git@...URLs).
Clone using SSH (common):
git-mirror [email protected]:owner/repo.gitClone using HTTPS:
git-mirror https://github.com/owner/repo.gitClone from GitLab (example):
git-mirror [email protected]:group/project.gitTo just print a cd command you can evaluate the output in your shell:
eval "$(git-mirror [email protected]:owner/repo.git --print-cd)"Basic CLI options:
-r, --root <ROOT>- Root directory where projects are stored (default:~/Projects). Example:git-mirror --root ~/Work [email protected]:owner/repo.git--print-cd- Print a shell-friendlycdcommand pointing to the repo local path. Example:git-mirror --print-cd [email protected]:owner/repo.git--dry-run- Dry run: show commands without executing. Example:git-mirror --dry-run [email protected]:owner/repo.git--open-vs-code- Open the repo in VS Code after cloning or when it already exists. Example:git-mirror --open-vs-code [email protected]:owner/repo.git--no-open-vs-code- Do not open the repo in VS Code. Example:git-mirror --no-open-vs-code [email protected]:owner/repo.git--no-prompt- Disable interactive prompts (useful in CI). Example:git-mirror --no-prompt [email protected]:owner/repo.git--full-host- Use the full host domain in the local path (e.g.github.cominstead ofgithub). Example:git-mirror --full-host [email protected]:owner/repo.git
Notes:
-
The CLI cannot change your parent shell's working directory. To have your interactive shell move into the cloned repo automatically, evaluate the CLI output in your shell.
Bash / Zsh example:
eval "$(git-mirror [email protected]:owner/repo.git --print-cd)"
Fish example:
eval (git-mirror [email protected]:owner/repo.git --print-cd)
-
If you want only the
cd(without opening an editor), use--print-cd.
Copy-paste helper functions for your shell.
Bash / Zsh:
git_mirror_cd() {
eval "$(git-mirror "$1" --print-cd ${2:+--root "$2"})"
}Fish:
function git_mirror_cd
set -l repo $argv[1]
set -l root_arg ''
if test (count $argv) -ge 2
set root_arg "--root $argv[2]"
end
eval (git-mirror $repo --print-cd $root_arg)
endPowerShell:
function Git-Mirror-Cd {
param([string]$Repo, [string]$Root)
if ($Root) {
$cmd = git-mirror $Repo --print-cd --root "$Root"
} else {
$cmd = git-mirror $Repo --print-cd
}
Invoke-Expression $cmd
}- This repo previously contained a Deno/TypeScript implementation, which has been replaced with the current Rust implementation.
- The Rust CLI implements core features: host parsing, local path construction,
git clone, VS Code integration, and interactive prompts.
The Rust implementation uses a short host label by default when constructing the local path. For example:
[email protected]:owner/repo.git->~/Projects/github/owner/repo
If you prefer the full domain (e.g. github.com) in the local path, use the
--full-host flag:
git-mirror --full-host [email protected]:owner/repo.git
# => ~/Projects/github.com/owner/repoIf you are migrating from an earlier implementation that used the full domain
in local paths, consider running a one-time move of your directories or cloning
with --full-host to keep the old layout.
If you want me to add an automatic migration helper (move directories and create symlinks), say so and I can implement it.
Developer and contributor information has moved to CONTRIBUTING.md.
See CONTRIBUTING.md for release automation, contributing, and troubleshooting details.