4 releases (2 breaking)

Uses new Rust 2024

new 0.3.1 Feb 9, 2026
0.3.0 Feb 7, 2026
0.2.0 Feb 6, 2026
0.1.0 Feb 6, 2026

#171 in Development tools

MIT license

60KB
1.5K SLoC

gemote

Crates.io CI Coverage License: MIT

Declarative git remote management. Define your remotes in a .gemote file, commit it, and keep the whole team in sync.

Install

From crates.io

cargo install gemote

From source

cargo install --path .

Pre-built binaries

Built and attested binaries are available for Linux, macOS, and Windows. Download from GitHub Releases

Docker

docker run --rm -v "$(pwd):/repo" -w /repo ghcr.io/twangodev/gemote sync

Usage

gemote save

Write your current local remotes into a .gemote file:

gemote save
gemote save -f            # replace existing .gemote (--force)
gemote save -r            # recursive mode (--recursive)

gemote sync

Set your local remotes to match the .gemote config:

gemote sync
gemote sync --dry-run     # preview changes without applying
gemote sync -r            # recursive mode (--recursive)

Global flags

--config <path>   Path to config file (default: .gemote at repo root)
--repo <path>     Path to git repository (default: discovered from cwd)

Config format

.gemote uses TOML:

[settings]
# What to do with local remotes not in this file: "ignore" (default), "warn", "remove"
extra_remotes = "ignore"

[remotes.origin]
url = "git@github.com:org/repo.git"

[remotes.upstream]
url = "git@github.com:upstream/repo.git"
push_url = "git@github.com:you/repo.git"  # optional, only if push URL differs

Recursive / submodule config

When using -r/--recursive, gemote automatically discovers git submodules and nested repos. Their remotes are stored under [submodules."<path>"]:

[remotes.origin]
url = "git@github.com:org/repo.git"

[submodules."libs/core".remotes.origin]
url = "git@github.com:org/core.git"

[submodules."libs/core".remotes.upstream]
url = "git@github.com:upstream/core.git"

Dependencies

~11–15MB
~321K SLoC