Manage multiple git repositories with ease
Project description
gitmux
Manage multiple git repositories with ease. Clone, pull, push, and run commands across repos with a single command.
Features
- YAML configuration — declarative repo management
- Group management — organize repos into groups
- Batch git operations — clone/pull/push across repos
- Pre/post hooks — run commands before/after git operations (e.g.,
npm installafter pull) - Template system — share hook configs across similar repos
- Parallel execution — speed up operations with
--parallelflag - Status overview — see all repos' git status at a glance
- Arbitrary command execution — run any shell command across repos
Install
pip install gitmux
Quick Start
# Initialize config in current directory
gitmux init
# Add repos (default group if --group omitted)
gitmux add git@github.com:user/api-server.git --group backend
gitmux add git@github.com:user/auth-service.git --group backend
# Clone all repos
gitmux clone --all
# Pull a single repo
gitmux pull backend/api-server
# Pull entire group (parallel)
gitmux pull --group backend --parallel
# Check status of all repos
gitmux status
# Run command on a specific repo
gitmux exec "git checkout main" --target backend/api-server
Configuration
Config file lookup order (used for both reading and writing):
--config / -cflag (explicit path).gitmux.yamlin current directory~/.gitmux.yaml(global fallback)
workspace: ~/projects
templates:
node-app:
post_pull:
- npm install
pre_push:
- npm test
groups:
backend:
repos:
- name: api-server
url: git@github.com:user/api-server.git
template: node-app
- name: auth-service
url: git@github.com:user/auth-service.git
path: ~/custom/path/auth # override default path
hooks:
post_pull:
- pip install -r requirements.txt
frontend:
repos:
- name: web-app
url: git@github.com:user/web-app.git
template: node-app
Path Resolution
- Default:
{workspace}/{group}/{repo_name} - Override per-repo with the
pathfield
Branch Management
Configure named branch aliases per repo:
repos:
- name: map
url: https://code.example.com/base/map.git
branches:
prod: "bInfinite-plan-*" # pattern (contains *)
dev: "bInfinite-dev-main" # fixed branch name
Usage:
gitmux pull map --branch dev # checkout fixed branch → pull
gitmux pull map --branch prod:latest # fetch → find newest matching branch → checkout → pull
gitmux pull map --branch prod:260515 # replace * → checkout bInfinite-plan-260515 → pull
gitmux pull --group base --branch dev # checkout fixed branch for all repos in group
Rules:
--branch <alias>— alias must be a fixed branch (no*), otherwise error--branch <alias>:latest— alias must be a pattern (has*), picks newest by commit date--branch <alias>:<value>— alias must be a pattern, replaces*with<value>
Hook System
Hooks run shell commands before/after git operations:
pre_clone,post_clonepre_pull,post_pullpre_push,post_push
Error handling:
- Pre-hook failure → git operation is skipped
- Post-hook failure → repo marked as failed
Template merging: Repo-level hooks override template hooks per hook type.
Commands
| Command | Description |
|---|---|
gitmux init |
Create .gitmux.yaml in current dir (--global for ~/.gitmux.yaml) |
gitmux add <url> --group <g> |
Add a repository (group auto-created) |
gitmux remove <name> |
Remove a repository |
gitmux list |
List all repositories |
gitmux status [target] |
Show git status overview (defaults to all) |
gitmux clone <target> |
Clone unclosed repositories |
gitmux fetch <target> |
Fetch remote data (--branches to list branches) |
gitmux pull <target> |
Pull latest changes |
gitmux push <target> |
Push local commits |
gitmux exec <cmd> |
Run command in repos (--target to specify) |
gitmux group list |
List groups |
gitmux group create <name> |
Create a group |
gitmux group remove <name> |
Remove a group |
Target Syntax
gitmux pull map # repo 'map' in default group
gitmux pull base/map # repo 'map' in group 'base'
gitmux pull --group base # all repos in group 'base'
gitmux pull --all # all repos (explicit)
gitmux pull # error: specify target, --group, or --all
Note: gitmux add <url> without --group places the repo in the default group.
Common Options
--group, -g— operate on entire group--all, -a— operate on all repositories (required for write operations without target)--parallel, -p— run in parallel (clone/fetch/pull/push/exec)--config, -c— custom config file path
Development
git clone https://github.com/ryan/gitmux.git
cd gitmux
pip install -e ".[dev]"
pytest
Code Quality
Uses Ruff for linting and formatting:
ruff check . # lint
ruff check --fix . # auto-fix
ruff format . # format
Rules: E, F, W, I (isort), N, UP (modern Python), B (bugbear), SIM.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gitmux-0.1.0.tar.gz.
File metadata
- Download URL: gitmux-0.1.0.tar.gz
- Upload date:
- Size: 16.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
86027d357b2e62b8598fbbd804ad02627cde80b9cc645d534a6162ccf2094798
|
|
| MD5 |
ffb8a7a300550099a131b6a13b5eded3
|
|
| BLAKE2b-256 |
bc9ae83d0a014543c6f6dfea0dfa68408ba35bdac6179baeac3a2a77b09cf37d
|
Provenance
The following attestation bundles were made for gitmux-0.1.0.tar.gz:
Publisher:
publish.yml on ryanwx/gitmux
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gitmux-0.1.0.tar.gz -
Subject digest:
86027d357b2e62b8598fbbd804ad02627cde80b9cc645d534a6162ccf2094798 - Sigstore transparency entry: 1601544271
- Sigstore integration time:
-
Permalink:
ryanwx/gitmux@544d72e1d9c9dc8c53df70ffd89e19b2af3a35ef -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ryanwx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@544d72e1d9c9dc8c53df70ffd89e19b2af3a35ef -
Trigger Event:
push
-
Statement type:
File details
Details for the file gitmux-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gitmux-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c9245c722dde07754bd8726b3b829051ec7d6b24bfd5a6634fd3fac9b82250c
|
|
| MD5 |
ace788368a7937d82f893e503120a176
|
|
| BLAKE2b-256 |
22737c533ce3aa43ea415ce639603b2ab7909b9abfe5702a7903b0b55745fdb4
|
Provenance
The following attestation bundles were made for gitmux-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on ryanwx/gitmux
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gitmux-0.1.0-py3-none-any.whl -
Subject digest:
8c9245c722dde07754bd8726b3b829051ec7d6b24bfd5a6634fd3fac9b82250c - Sigstore transparency entry: 1601544369
- Sigstore integration time:
-
Permalink:
ryanwx/gitmux@544d72e1d9c9dc8c53df70ffd89e19b2af3a35ef -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ryanwx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@544d72e1d9c9dc8c53df70ffd89e19b2af3a35ef -
Trigger Event:
push
-
Statement type: