gitmux 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ id-token: write
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.12"
19
+
20
+ - name: Install build tools
21
+ run: pip install build
22
+
23
+ - name: Build package
24
+ run: python -m build
25
+
26
+ - name: Publish to PyPI
27
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,8 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ dist/
4
+ build/
5
+ .pytest_cache/
6
+ *.pyc
7
+ .venv/
8
+ .idea
gitmux-0.1.0/DESIGN.md ADDED
@@ -0,0 +1,96 @@
1
+ # gitmux - Design Document
2
+
3
+ ## Overview
4
+
5
+ gitmux 是一个 Python CLI 工具,通过 YAML 配置文件管理多个 git 仓库,支持批量 git 操作、分组管理、前后置 hook、并行/串行执行模式。
6
+
7
+ ## Architecture
8
+
9
+ ```
10
+ src/gitmux/
11
+ ├── cli.py # Typer CLI 入口,子命令定义
12
+ ├── config.py # YAML 配置加载/验证/保存
13
+ ├── models.py # 数据模型(Repo, Group, Hook, Template)
14
+ ├── executor.py # 命令执行引擎(串行/并行)
15
+ ├── git_ops.py # Git 操作封装
16
+ ├── hooks.py # Hook 执行逻辑
17
+ └── output.py # 输出格式化(Rich 表格、进度条)
18
+ ```
19
+
20
+ ## Configuration Format
21
+
22
+ ```yaml
23
+ workspace: ~/projects
24
+
25
+ templates:
26
+ node-app:
27
+ post_pull:
28
+ - npm install
29
+ pre_push:
30
+ - npm test
31
+
32
+ groups:
33
+ backend:
34
+ repos:
35
+ - name: api-server
36
+ url: git@github.com:user/api-server.git
37
+ template: node-app
38
+ - name: auth-service
39
+ url: git@github.com:user/auth-service.git
40
+ path: ~/custom/path/auth
41
+ hooks:
42
+ post_pull:
43
+ - pip install -r requirements.txt
44
+ branches:
45
+ prod: "auth-plan-*"
46
+ dev: "auth-dev-main"
47
+ frontend:
48
+ repos:
49
+ - name: web-app
50
+ url: git@github.com:user/web-app.git
51
+ template: node-app
52
+ ```
53
+
54
+ ## CLI Commands
55
+
56
+ ```
57
+ gitmux init # 初始化配置文件
58
+ gitmux add <url> --group=<group> # 添加仓库
59
+ gitmux remove <name> # 移除仓库
60
+ gitmux list # 列出所有仓库
61
+ gitmux status [--group=<group>] # 状态总览
62
+ gitmux clone [--group=<group>] # 克隆未克隆的仓库
63
+ gitmux fetch [--group=<group>] [--branches] [--parallel]
64
+ gitmux pull [--group=<group>] [--branch=<alias|alias:latest|alias:value>] [--parallel]
65
+ gitmux push [--group=<group>] [--parallel]
66
+ gitmux exec <command> [--group=<group>] [--parallel]
67
+ gitmux group list
68
+ gitmux group create <name>
69
+ gitmux group remove <name>
70
+ ```
71
+
72
+ ## Execution Flow
73
+
74
+ 1. 用户执行命令
75
+ 2. 查找配置文件:`--config` 指定 → 当前目录 `.gitmux.yaml` → `~/.gitmux.yaml`
76
+ 3. 加载配置,解析目标仓库列表(按 --group 过滤)
77
+ 3. 判断串行/并行模式
78
+ 4. 对每个仓库执行:pre-hook → git 操作 → post-hook
79
+ 5. 输出结果
80
+
81
+ ### Hook 错误处理
82
+ - pre-hook 失败 → 中断该仓库的 git 操作
83
+ - post-hook 失败 → 标记仓库失败
84
+
85
+ ### 输出模式
86
+ - 串行:实时输出,显示当前仓库名和执行步骤
87
+ - 并行:Rich 进度条,完成后汇总(成功/失败/详情)
88
+
89
+ ## Technical Stack
90
+ - CLI: Typer
91
+ - Terminal UI: Rich
92
+ - Config: PyYAML
93
+ - Parallelism: concurrent.futures.ThreadPoolExecutor
94
+ - Git: subprocess
95
+ - Testing: pytest
96
+ - Build: hatchling
gitmux-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ryan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
gitmux-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: gitmux
3
+ Version: 0.1.0
4
+ Summary: Manage multiple git repositories with ease
5
+ Project-URL: Homepage, https://github.com/ryan/gitmux
6
+ Project-URL: Repository, https://github.com/ryan/gitmux
7
+ Project-URL: Issues, https://github.com/ryan/gitmux/issues
8
+ Author: Ryan
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: cli,devtools,git,multi-repo
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Version Control :: Git
22
+ Requires-Python: >=3.10
23
+ Requires-Dist: pyyaml>=6.0.2
24
+ Requires-Dist: rich>=13.9.4
25
+ Requires-Dist: typer>=0.15.4
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest-mock==3.14.0; extra == 'dev'
28
+ Requires-Dist: pytest==8.3.4; extra == 'dev'
29
+ Requires-Dist: ruff==0.11.12; extra == 'dev'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # gitmux
33
+
34
+ Manage multiple git repositories with ease. Clone, pull, push, and run commands across repos with a single command.
35
+
36
+ ## Features
37
+
38
+ - **YAML configuration** — declarative repo management
39
+ - **Group management** — organize repos into groups
40
+ - **Batch git operations** — clone/pull/push across repos
41
+ - **Pre/post hooks** — run commands before/after git operations (e.g., `npm install` after pull)
42
+ - **Template system** — share hook configs across similar repos
43
+ - **Parallel execution** — speed up operations with `--parallel` flag
44
+ - **Status overview** — see all repos' git status at a glance
45
+ - **Arbitrary command execution** — run any shell command across repos
46
+
47
+ ## Install
48
+
49
+ ```bash
50
+ pip install gitmux
51
+ ```
52
+
53
+ ## Quick Start
54
+
55
+ ```bash
56
+ # Initialize config in current directory
57
+ gitmux init
58
+
59
+ # Add repos (default group if --group omitted)
60
+ gitmux add git@github.com:user/api-server.git --group backend
61
+ gitmux add git@github.com:user/auth-service.git --group backend
62
+
63
+ # Clone all repos
64
+ gitmux clone --all
65
+
66
+ # Pull a single repo
67
+ gitmux pull backend/api-server
68
+
69
+ # Pull entire group (parallel)
70
+ gitmux pull --group backend --parallel
71
+
72
+ # Check status of all repos
73
+ gitmux status
74
+
75
+ # Run command on a specific repo
76
+ gitmux exec "git checkout main" --target backend/api-server
77
+ ```
78
+
79
+ ## Configuration
80
+
81
+ Config file lookup order (used for both reading and writing):
82
+ 1. `--config / -c` flag (explicit path)
83
+ 2. `.gitmux.yaml` in current directory
84
+ 3. `~/.gitmux.yaml` (global fallback)
85
+
86
+ ```yaml
87
+ workspace: ~/projects
88
+
89
+ templates:
90
+ node-app:
91
+ post_pull:
92
+ - npm install
93
+ pre_push:
94
+ - npm test
95
+
96
+ groups:
97
+ backend:
98
+ repos:
99
+ - name: api-server
100
+ url: git@github.com:user/api-server.git
101
+ template: node-app
102
+ - name: auth-service
103
+ url: git@github.com:user/auth-service.git
104
+ path: ~/custom/path/auth # override default path
105
+ hooks:
106
+ post_pull:
107
+ - pip install -r requirements.txt
108
+ frontend:
109
+ repos:
110
+ - name: web-app
111
+ url: git@github.com:user/web-app.git
112
+ template: node-app
113
+ ```
114
+
115
+ ### Path Resolution
116
+
117
+ - Default: `{workspace}/{group}/{repo_name}`
118
+ - Override per-repo with the `path` field
119
+
120
+ ### Branch Management
121
+
122
+ Configure named branch aliases per repo:
123
+
124
+ ```yaml
125
+ repos:
126
+ - name: map
127
+ url: https://code.example.com/base/map.git
128
+ branches:
129
+ prod: "bInfinite-plan-*" # pattern (contains *)
130
+ dev: "bInfinite-dev-main" # fixed branch name
131
+ ```
132
+
133
+ Usage:
134
+
135
+ ```bash
136
+ gitmux pull map --branch dev # checkout fixed branch → pull
137
+ gitmux pull map --branch prod:latest # fetch → find newest matching branch → checkout → pull
138
+ gitmux pull map --branch prod:260515 # replace * → checkout bInfinite-plan-260515 → pull
139
+ gitmux pull --group base --branch dev # checkout fixed branch for all repos in group
140
+ ```
141
+
142
+ Rules:
143
+ - `--branch <alias>` — alias must be a fixed branch (no `*`), otherwise error
144
+ - `--branch <alias>:latest` — alias must be a pattern (has `*`), picks newest by commit date
145
+ - `--branch <alias>:<value>` — alias must be a pattern, replaces `*` with `<value>`
146
+
147
+ ### Hook System
148
+
149
+ Hooks run shell commands before/after git operations:
150
+
151
+ - `pre_clone`, `post_clone`
152
+ - `pre_pull`, `post_pull`
153
+ - `pre_push`, `post_push`
154
+
155
+ **Error handling:**
156
+ - Pre-hook failure → git operation is skipped
157
+ - Post-hook failure → repo marked as failed
158
+
159
+ **Template merging:** Repo-level hooks override template hooks per hook type.
160
+
161
+ ## Commands
162
+
163
+ | Command | Description |
164
+ |---------|-------------|
165
+ | `gitmux init` | Create `.gitmux.yaml` in current dir (`--global` for `~/.gitmux.yaml`) |
166
+ | `gitmux add <url> --group <g>` | Add a repository (group auto-created) |
167
+ | `gitmux remove <name>` | Remove a repository |
168
+ | `gitmux list` | List all repositories |
169
+ | `gitmux status [target]` | Show git status overview (defaults to all) |
170
+ | `gitmux clone <target>` | Clone unclosed repositories |
171
+ | `gitmux fetch <target>` | Fetch remote data (`--branches` to list branches) |
172
+ | `gitmux pull <target>` | Pull latest changes |
173
+ | `gitmux push <target>` | Push local commits |
174
+ | `gitmux exec <cmd>` | Run command in repos (`--target` to specify) |
175
+ | `gitmux group list` | List groups |
176
+ | `gitmux group create <name>` | Create a group |
177
+ | `gitmux group remove <name>` | Remove a group |
178
+
179
+ ### Target Syntax
180
+
181
+ ```bash
182
+ gitmux pull map # repo 'map' in default group
183
+ gitmux pull base/map # repo 'map' in group 'base'
184
+ gitmux pull --group base # all repos in group 'base'
185
+ gitmux pull --all # all repos (explicit)
186
+ gitmux pull # error: specify target, --group, or --all
187
+ ```
188
+
189
+ Note: `gitmux add <url>` without `--group` places the repo in the `default` group.
190
+
191
+ ### Common Options
192
+
193
+ - `--group, -g` — operate on entire group
194
+ - `--all, -a` — operate on all repositories (required for write operations without target)
195
+ - `--parallel, -p` — run in parallel (clone/fetch/pull/push/exec)
196
+ - `--config, -c` — custom config file path
197
+
198
+ ## Development
199
+
200
+ ```bash
201
+ git clone https://github.com/ryan/gitmux.git
202
+ cd gitmux
203
+ pip install -e ".[dev]"
204
+ pytest
205
+ ```
206
+
207
+ ### Code Quality
208
+
209
+ Uses [Ruff](https://docs.astral.sh/ruff/) for linting and formatting:
210
+
211
+ ```bash
212
+ ruff check . # lint
213
+ ruff check --fix . # auto-fix
214
+ ruff format . # format
215
+ ```
216
+
217
+ Rules: `E`, `F`, `W`, `I` (isort), `N`, `UP` (modern Python), `B` (bugbear), `SIM`.
218
+
219
+ ## License
220
+
221
+ MIT
gitmux-0.1.0/README.md ADDED
@@ -0,0 +1,190 @@
1
+ # gitmux
2
+
3
+ Manage multiple git repositories with ease. Clone, pull, push, and run commands across repos with a single command.
4
+
5
+ ## Features
6
+
7
+ - **YAML configuration** — declarative repo management
8
+ - **Group management** — organize repos into groups
9
+ - **Batch git operations** — clone/pull/push across repos
10
+ - **Pre/post hooks** — run commands before/after git operations (e.g., `npm install` after pull)
11
+ - **Template system** — share hook configs across similar repos
12
+ - **Parallel execution** — speed up operations with `--parallel` flag
13
+ - **Status overview** — see all repos' git status at a glance
14
+ - **Arbitrary command execution** — run any shell command across repos
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ pip install gitmux
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```bash
25
+ # Initialize config in current directory
26
+ gitmux init
27
+
28
+ # Add repos (default group if --group omitted)
29
+ gitmux add git@github.com:user/api-server.git --group backend
30
+ gitmux add git@github.com:user/auth-service.git --group backend
31
+
32
+ # Clone all repos
33
+ gitmux clone --all
34
+
35
+ # Pull a single repo
36
+ gitmux pull backend/api-server
37
+
38
+ # Pull entire group (parallel)
39
+ gitmux pull --group backend --parallel
40
+
41
+ # Check status of all repos
42
+ gitmux status
43
+
44
+ # Run command on a specific repo
45
+ gitmux exec "git checkout main" --target backend/api-server
46
+ ```
47
+
48
+ ## Configuration
49
+
50
+ Config file lookup order (used for both reading and writing):
51
+ 1. `--config / -c` flag (explicit path)
52
+ 2. `.gitmux.yaml` in current directory
53
+ 3. `~/.gitmux.yaml` (global fallback)
54
+
55
+ ```yaml
56
+ workspace: ~/projects
57
+
58
+ templates:
59
+ node-app:
60
+ post_pull:
61
+ - npm install
62
+ pre_push:
63
+ - npm test
64
+
65
+ groups:
66
+ backend:
67
+ repos:
68
+ - name: api-server
69
+ url: git@github.com:user/api-server.git
70
+ template: node-app
71
+ - name: auth-service
72
+ url: git@github.com:user/auth-service.git
73
+ path: ~/custom/path/auth # override default path
74
+ hooks:
75
+ post_pull:
76
+ - pip install -r requirements.txt
77
+ frontend:
78
+ repos:
79
+ - name: web-app
80
+ url: git@github.com:user/web-app.git
81
+ template: node-app
82
+ ```
83
+
84
+ ### Path Resolution
85
+
86
+ - Default: `{workspace}/{group}/{repo_name}`
87
+ - Override per-repo with the `path` field
88
+
89
+ ### Branch Management
90
+
91
+ Configure named branch aliases per repo:
92
+
93
+ ```yaml
94
+ repos:
95
+ - name: map
96
+ url: https://code.example.com/base/map.git
97
+ branches:
98
+ prod: "bInfinite-plan-*" # pattern (contains *)
99
+ dev: "bInfinite-dev-main" # fixed branch name
100
+ ```
101
+
102
+ Usage:
103
+
104
+ ```bash
105
+ gitmux pull map --branch dev # checkout fixed branch → pull
106
+ gitmux pull map --branch prod:latest # fetch → find newest matching branch → checkout → pull
107
+ gitmux pull map --branch prod:260515 # replace * → checkout bInfinite-plan-260515 → pull
108
+ gitmux pull --group base --branch dev # checkout fixed branch for all repos in group
109
+ ```
110
+
111
+ Rules:
112
+ - `--branch <alias>` — alias must be a fixed branch (no `*`), otherwise error
113
+ - `--branch <alias>:latest` — alias must be a pattern (has `*`), picks newest by commit date
114
+ - `--branch <alias>:<value>` — alias must be a pattern, replaces `*` with `<value>`
115
+
116
+ ### Hook System
117
+
118
+ Hooks run shell commands before/after git operations:
119
+
120
+ - `pre_clone`, `post_clone`
121
+ - `pre_pull`, `post_pull`
122
+ - `pre_push`, `post_push`
123
+
124
+ **Error handling:**
125
+ - Pre-hook failure → git operation is skipped
126
+ - Post-hook failure → repo marked as failed
127
+
128
+ **Template merging:** Repo-level hooks override template hooks per hook type.
129
+
130
+ ## Commands
131
+
132
+ | Command | Description |
133
+ |---------|-------------|
134
+ | `gitmux init` | Create `.gitmux.yaml` in current dir (`--global` for `~/.gitmux.yaml`) |
135
+ | `gitmux add <url> --group <g>` | Add a repository (group auto-created) |
136
+ | `gitmux remove <name>` | Remove a repository |
137
+ | `gitmux list` | List all repositories |
138
+ | `gitmux status [target]` | Show git status overview (defaults to all) |
139
+ | `gitmux clone <target>` | Clone unclosed repositories |
140
+ | `gitmux fetch <target>` | Fetch remote data (`--branches` to list branches) |
141
+ | `gitmux pull <target>` | Pull latest changes |
142
+ | `gitmux push <target>` | Push local commits |
143
+ | `gitmux exec <cmd>` | Run command in repos (`--target` to specify) |
144
+ | `gitmux group list` | List groups |
145
+ | `gitmux group create <name>` | Create a group |
146
+ | `gitmux group remove <name>` | Remove a group |
147
+
148
+ ### Target Syntax
149
+
150
+ ```bash
151
+ gitmux pull map # repo 'map' in default group
152
+ gitmux pull base/map # repo 'map' in group 'base'
153
+ gitmux pull --group base # all repos in group 'base'
154
+ gitmux pull --all # all repos (explicit)
155
+ gitmux pull # error: specify target, --group, or --all
156
+ ```
157
+
158
+ Note: `gitmux add <url>` without `--group` places the repo in the `default` group.
159
+
160
+ ### Common Options
161
+
162
+ - `--group, -g` — operate on entire group
163
+ - `--all, -a` — operate on all repositories (required for write operations without target)
164
+ - `--parallel, -p` — run in parallel (clone/fetch/pull/push/exec)
165
+ - `--config, -c` — custom config file path
166
+
167
+ ## Development
168
+
169
+ ```bash
170
+ git clone https://github.com/ryan/gitmux.git
171
+ cd gitmux
172
+ pip install -e ".[dev]"
173
+ pytest
174
+ ```
175
+
176
+ ### Code Quality
177
+
178
+ Uses [Ruff](https://docs.astral.sh/ruff/) for linting and formatting:
179
+
180
+ ```bash
181
+ ruff check . # lint
182
+ ruff check --fix . # auto-fix
183
+ ruff format . # format
184
+ ```
185
+
186
+ Rules: `E`, `F`, `W`, `I` (isort), `N`, `UP` (modern Python), `B` (bugbear), `SIM`.
187
+
188
+ ## License
189
+
190
+ MIT
@@ -0,0 +1,62 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "gitmux"
7
+ version = "0.1.0"
8
+ description = "Manage multiple git repositories with ease"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "Ryan" }]
13
+ keywords = ["git", "multi-repo", "cli", "devtools"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Topic :: Software Development :: Version Control :: Git",
25
+ ]
26
+ dependencies = [
27
+ "typer>=0.15.4",
28
+ "rich>=13.9.4",
29
+ "pyyaml>=6.0.2",
30
+ ]
31
+
32
+ [project.optional-dependencies]
33
+ dev = [
34
+ "pytest==8.3.4",
35
+ "pytest-mock==3.14.0",
36
+ "ruff==0.11.12",
37
+ ]
38
+
39
+ [project.scripts]
40
+ gitmux = "gitmux.cli:app"
41
+
42
+ [project.urls]
43
+ Homepage = "https://github.com/ryan/gitmux"
44
+ Repository = "https://github.com/ryan/gitmux"
45
+ Issues = "https://github.com/ryan/gitmux/issues"
46
+
47
+ [tool.hatch.build.targets.wheel]
48
+ packages = ["src/gitmux"]
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]
52
+
53
+ [tool.ruff]
54
+ target-version = "py310"
55
+ line-length = 120
56
+
57
+ [tool.ruff.lint]
58
+ select = ["E", "F", "W", "I", "N", "UP", "B", "SIM"]
59
+ ignore = ["E501"]
60
+
61
+ [tool.ruff.lint.isort]
62
+ known-first-party = ["gitmux"]
@@ -0,0 +1,3 @@
1
+ """gitmux - Manage multiple git repositories with ease."""
2
+
3
+ __version__ = "0.1.0"