marshal-branch-manager 4.0.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.
Files changed (43) hide show
  1. marshal_branch_manager-4.0.0/.cache/pip/http-v2/3/a/9/0/a/3a90a4636ff8a0016bbb5ae63eff66f7ed5689db21aa1584b5f7036f +0 -0
  2. marshal_branch_manager-4.0.0/.cache/pip/http-v2/3/a/9/0/a/3a90a4636ff8a0016bbb5ae63eff66f7ed5689db21aa1584b5f7036f.body +355 -0
  3. marshal_branch_manager-4.0.0/.cache/pip/http-v2/5/f/7/3/c/5f73c55638bab0e38deb49e63e1b83a8d874933898591baf17441634 +0 -0
  4. marshal_branch_manager-4.0.0/.cache/pip/http-v2/5/f/7/3/c/5f73c55638bab0e38deb49e63e1b83a8d874933898591baf17441634.body +0 -0
  5. marshal_branch_manager-4.0.0/.cache/pip/http-v2/a/1/9/5/3/a19537d3cf37c122db841d6fe4cd322bc10d1a558bb00d146b85cb9a +0 -0
  6. marshal_branch_manager-4.0.0/.cache/pip/http-v2/a/1/9/5/3/a19537d3cf37c122db841d6fe4cd322bc10d1a558bb00d146b85cb9a.body +0 -0
  7. marshal_branch_manager-4.0.0/.cache/pip/http-v2/a/d/e/e/f/adeef5b9611702687bbddade5f7c0af65110caf98ba1a0070c9d116e +0 -0
  8. marshal_branch_manager-4.0.0/.cache/pip/http-v2/a/d/e/e/f/adeef5b9611702687bbddade5f7c0af65110caf98ba1a0070c9d116e.body +0 -0
  9. marshal_branch_manager-4.0.0/.cache/pip/selfcheck/fe300af6f7d708c14827daac3afc81fbb8306b73de8dd6e3f1f8ea3b +1 -0
  10. marshal_branch_manager-4.0.0/.gitignore +25 -0
  11. marshal_branch_manager-4.0.0/.gitlab-ci.yml +61 -0
  12. marshal_branch_manager-4.0.0/.pre-commit-config.yaml +25 -0
  13. marshal_branch_manager-4.0.0/.python-version +1 -0
  14. marshal_branch_manager-4.0.0/CHANGELOG.md +6 -0
  15. marshal_branch_manager-4.0.0/CLAUDE.md +186 -0
  16. marshal_branch_manager-4.0.0/LICENSE +21 -0
  17. marshal_branch_manager-4.0.0/PKG-INFO +273 -0
  18. marshal_branch_manager-4.0.0/README.md +257 -0
  19. marshal_branch_manager-4.0.0/docs/gitlab_mr_example.png +0 -0
  20. marshal_branch_manager-4.0.0/pyproject.toml +59 -0
  21. marshal_branch_manager-4.0.0/src/marshal_branch_manager/__init__.py +5 -0
  22. marshal_branch_manager-4.0.0/src/marshal_branch_manager/__main__.py +6 -0
  23. marshal_branch_manager-4.0.0/src/marshal_branch_manager/_version.py +24 -0
  24. marshal_branch_manager-4.0.0/src/marshal_branch_manager/branch_sync.py +108 -0
  25. marshal_branch_manager-4.0.0/src/marshal_branch_manager/cli.py +347 -0
  26. marshal_branch_manager-4.0.0/src/marshal_branch_manager/config.py +176 -0
  27. marshal_branch_manager-4.0.0/src/marshal_branch_manager/exceptions.py +59 -0
  28. marshal_branch_manager-4.0.0/src/marshal_branch_manager/git.py +413 -0
  29. marshal_branch_manager-4.0.0/src/marshal_branch_manager/github.py +132 -0
  30. marshal_branch_manager-4.0.0/src/marshal_branch_manager/pr.py +144 -0
  31. marshal_branch_manager-4.0.0/src/marshal_branch_manager/rebase.py +580 -0
  32. marshal_branch_manager-4.0.0/src/marshal_branch_manager/rerere.py +161 -0
  33. marshal_branch_manager-4.0.0/src/marshal_branch_manager/trailers.py +156 -0
  34. marshal_branch_manager-4.0.0/src/marshal_branch_manager/update_branch.py +112 -0
  35. marshal_branch_manager-4.0.0/tests/conftest.py +151 -0
  36. marshal_branch_manager-4.0.0/tests/test_branch_sync.py +143 -0
  37. marshal_branch_manager-4.0.0/tests/test_config.py +282 -0
  38. marshal_branch_manager-4.0.0/tests/test_exceptions.py +54 -0
  39. marshal_branch_manager-4.0.0/tests/test_git.py +331 -0
  40. marshal_branch_manager-4.0.0/tests/test_github.py +99 -0
  41. marshal_branch_manager-4.0.0/tests/test_integration.py +368 -0
  42. marshal_branch_manager-4.0.0/tests/test_trailers.py +191 -0
  43. marshal_branch_manager-4.0.0/tests/test_update_branch.py +103 -0
@@ -0,0 +1,355 @@
1
+ Metadata-Version: 2.4
2
+ Name: uv
3
+ Version: 0.13.7
4
+ Classifier: Development Status :: 5 - Production/Stable
5
+ Classifier: Environment :: Console
6
+ Classifier: Intended Audience :: Developers
7
+ Classifier: Operating System :: OS Independent
8
+ Classifier: Programming Language :: Python
9
+ Classifier: Programming Language :: Python :: 3.8
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Programming Language :: Python :: 3.15
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Rust
19
+ Classifier: Topic :: Software Development :: Quality Assurance
20
+ Classifier: Topic :: Software Development :: Testing
21
+ Classifier: Topic :: Software Development :: Libraries
22
+ License-File: LICENSE-APACHE
23
+ License-File: LICENSE-MIT
24
+ Summary: An extremely fast Python package and project manager, written in Rust.
25
+ Keywords: uv,requirements,packaging
26
+ Home-Page: https://pypi.org/project/uv/
27
+ Author-email: "Astral Software Inc." <hey@astral.sh>
28
+ License-Expression: MIT OR Apache-2.0
29
+ Requires-Python: >=3.8
30
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
31
+ Project-URL: Changelog, https://github.com/astral-sh/uv/blob/main/CHANGELOG.md
32
+ Project-URL: Discord, https://discord.gg/astral-sh
33
+ Project-URL: Documentation, https://docs.astral.sh/uv
34
+ Project-URL: Releases, https://github.com/astral-sh/uv/releases
35
+ Project-URL: Repository, https://github.com/astral-sh/uv
36
+
37
+ # uv
38
+
39
+ An extremely fast Python package and project manager, written in Rust.
40
+
41
+ <p align="center">
42
+ <img alt="Shows a bar chart with benchmark results." src="https://github.com/astral-sh/uv/assets/1309177/629e59c0-9c6e-4013-9ad4-adb2bcf5080d">
43
+ </p>
44
+
45
+ <p align="center">
46
+ <i>Installing <a href="https://trio.readthedocs.io/">Trio</a>'s dependencies with a warm cache.</i>
47
+ </p>
48
+
49
+ ## Highlights
50
+
51
+ - A single tool to replace `pip`, `pip-tools`, `pipx`, `poetry`, `pyenv`, `twine`, `virtualenv`, and
52
+ more.
53
+ - [10-100x faster](https://github.com/astral-sh/uv/blob/main/BENCHMARKS.md) than `pip`.
54
+ - Provides [comprehensive project management](https://github.com/astral-sh/uv/blob/0.13.7/README.md#projects), with a
55
+ [universal lockfile](https://docs.astral.sh/uv/concepts/projects/layout#the-lockfile).
56
+ - [Runs scripts](https://github.com/astral-sh/uv/blob/0.13.7/README.md#scripts), with support for
57
+ [inline dependency metadata](https://docs.astral.sh/uv/guides/scripts#declaring-script-dependencies).
58
+ - [Installs and manages](https://github.com/astral-sh/uv/blob/0.13.7/README.md#python-versions) Python versions.
59
+ - [Runs and installs](https://github.com/astral-sh/uv/blob/0.13.7/README.md#tools) tools published as Python packages.
60
+ - Includes a [pip-compatible interface](https://github.com/astral-sh/uv/blob/0.13.7/README.md#the-pip-interface) for a performance boost with a familiar
61
+ CLI.
62
+ - Supports Cargo-style [workspaces](https://docs.astral.sh/uv/concepts/projects/workspaces) for
63
+ scalable projects.
64
+ - Disk-space efficient, with a [global cache](https://docs.astral.sh/uv/concepts/cache) for
65
+ dependency deduplication.
66
+ - Installable without Rust or Python via `curl` or `pip`.
67
+ - Supports macOS, Linux, and Windows.
68
+
69
+ uv is backed by [Astral](https://astral.sh), the creators of
70
+ [Ruff](https://github.com/astral-sh/ruff) and [ty](https://github.com/astral-sh/ty).
71
+
72
+ ## Installation
73
+
74
+ Install uv with our standalone installers:
75
+
76
+ ```bash
77
+ # On macOS and Linux.
78
+ curl -LsSf https://astral.sh/uv/install.sh | sh
79
+ ```
80
+
81
+ ```bash
82
+ # On Windows.
83
+ powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
84
+ ```
85
+
86
+ Or, from [PyPI](https://pypi.org/project/uv/):
87
+
88
+ ```bash
89
+ # With pip.
90
+ pip install uv
91
+ ```
92
+
93
+ ```bash
94
+ # Or pipx.
95
+ pipx install uv
96
+ ```
97
+
98
+ If installed via the standalone installer, uv can update itself to the latest version:
99
+
100
+ ```bash
101
+ uv self update
102
+ ```
103
+
104
+ See the [installation documentation](https://docs.astral.sh/uv/getting-started/installation/) for
105
+ details and alternative installation methods.
106
+
107
+ ## Documentation
108
+
109
+ uv's documentation is available at [docs.astral.sh/uv](https://docs.astral.sh/uv).
110
+
111
+ Additionally, the command line reference documentation can be viewed with `uv help`.
112
+
113
+ ## Features
114
+
115
+ ### Projects
116
+
117
+ uv manages project dependencies and environments, with support for lockfiles, workspaces, and more,
118
+ similar to `rye` or `poetry`:
119
+
120
+ ```console
121
+ $ uv init example
122
+ Initialized project `example` at `/home/user/example`
123
+
124
+ $ cd example
125
+
126
+ $ uv add ruff
127
+ Creating virtual environment at: .venv
128
+ Resolved 2 packages in 170ms
129
+ Built example @ file:///home/user/example
130
+ Prepared 2 packages in 627ms
131
+ Installed 2 packages in 1ms
132
+ + example==0.1.0 (from file:///home/user/example)
133
+ + ruff==0.5.0
134
+
135
+ $ uv run ruff check
136
+ All checks passed!
137
+
138
+ $ uv lock
139
+ Resolved 2 packages in 0.33ms
140
+
141
+ $ uv sync
142
+ Resolved 2 packages in 0.70ms
143
+ Checked 1 package in 0.02ms
144
+ ```
145
+
146
+ See the [project documentation](https://docs.astral.sh/uv/guides/projects/) to get started.
147
+
148
+ uv also supports building and publishing projects, even if they're not managed with uv. See the
149
+ [publish guide](https://docs.astral.sh/uv/guides/publish/) to learn more.
150
+
151
+ ### Scripts
152
+
153
+ uv manages dependencies and environments for single-file scripts.
154
+
155
+ Create a new script and add inline metadata declaring its dependencies:
156
+
157
+ ```console
158
+ $ echo 'import requests; print(requests.get("https://astral.sh"))' > example.py
159
+
160
+ $ uv add --script example.py requests
161
+ Updated `example.py`
162
+ ```
163
+
164
+ Then, run the script in an isolated virtual environment:
165
+
166
+ ```console
167
+ $ uv run example.py
168
+ Reading inline script metadata from: example.py
169
+ Installed 5 packages in 12ms
170
+ <Response [200]>
171
+ ```
172
+
173
+ See the [scripts documentation](https://docs.astral.sh/uv/guides/scripts/) to get started.
174
+
175
+ ### Tools
176
+
177
+ uv executes and installs command-line tools provided by Python packages, similar to `pipx`.
178
+
179
+ Run a tool in an ephemeral environment using `uvx` (an alias for `uv tool run`):
180
+
181
+ ```console
182
+ $ uvx pycowsay 'hello world!'
183
+ Resolved 1 package in 167ms
184
+ Installed 1 package in 9ms
185
+ + pycowsay==0.0.0.2
186
+ """
187
+
188
+ ------------
189
+ < hello world! >
190
+ ------------
191
+ \ ^__^
192
+ \ (oo)\_______
193
+ (__)\ )\/\
194
+ ||----w |
195
+ || ||
196
+ ```
197
+
198
+ Install a tool with `uv tool install`:
199
+
200
+ ```console
201
+ $ uv tool install ruff
202
+ Resolved 1 package in 6ms
203
+ Installed 1 package in 2ms
204
+ + ruff==0.5.0
205
+ Installed 1 executable: ruff
206
+
207
+ $ ruff --version
208
+ ruff 0.5.0
209
+ ```
210
+
211
+ See the [tools documentation](https://docs.astral.sh/uv/guides/tools/) to get started.
212
+
213
+ ### Python versions
214
+
215
+ uv installs Python and allows quickly switching between versions.
216
+
217
+ Install multiple Python versions:
218
+
219
+ ```console
220
+ $ uv python install 3.12 3.13 3.14
221
+ Installed 3 versions in 972ms
222
+ + cpython-3.12.12-macos-aarch64-none (python3.12)
223
+ + cpython-3.13.9-macos-aarch64-none (python3.13)
224
+ + cpython-3.14.0-macos-aarch64-none (python3.14)
225
+
226
+ ```
227
+
228
+ Download Python versions as needed:
229
+
230
+ ```console
231
+ $ uv venv --python 3.12.0
232
+ Using Python 3.12.0
233
+ Creating virtual environment at: .venv
234
+ Activate with: source .venv/bin/activate
235
+
236
+ $ uv run --python pypy@3.8 -- python --version
237
+ Python 3.8.16 (a9dbdca6fc3286b0addd2240f11d97d8e8de187a, Dec 29 2022, 11:45:30)
238
+ [PyPy 7.3.11 with GCC Apple LLVM 13.1.6 (clang-1316.0.21.2.5)] on darwin
239
+ Type "help", "copyright", "credits" or "license" for more information.
240
+ >>>>
241
+ ```
242
+
243
+ Use a specific Python version in the current directory:
244
+
245
+ ```console
246
+ $ uv python pin 3.11
247
+ Pinned `.python-version` to `3.11`
248
+ ```
249
+
250
+ See the [Python installation documentation](https://docs.astral.sh/uv/guides/install-python/) to get
251
+ started.
252
+
253
+ ### The pip interface
254
+
255
+ uv provides a drop-in replacement for common `pip`, `pip-tools`, and `virtualenv` commands.
256
+
257
+ uv extends their interfaces with advanced features, such as dependency version overrides,
258
+ platform-independent resolutions, reproducible resolutions, alternative resolution strategies, and
259
+ more.
260
+
261
+ Migrate to uv without changing your existing workflows — and experience a 10-100x speedup — with the
262
+ `uv pip` interface.
263
+
264
+ Compile requirements into a platform-independent requirements file:
265
+
266
+ ```console
267
+ $ uv pip compile requirements.in \
268
+ --universal \
269
+ --output-file requirements.txt
270
+ Resolved 43 packages in 12ms
271
+ ```
272
+
273
+ Create a virtual environment:
274
+
275
+ ```console
276
+ $ uv venv
277
+ Using Python 3.12.3
278
+ Creating virtual environment at: .venv
279
+ Activate with: source .venv/bin/activate
280
+ ```
281
+
282
+ Install the locked requirements:
283
+
284
+ ```console
285
+ $ uv pip sync requirements.txt
286
+ Resolved 43 packages in 11ms
287
+ Installed 43 packages in 208ms
288
+ + babel==2.15.0
289
+ + black==24.4.2
290
+ + certifi==2024.7.4
291
+ ...
292
+ ```
293
+
294
+ See the [pip interface documentation](https://docs.astral.sh/uv/pip/index/) to get started.
295
+
296
+ ## Contributing
297
+
298
+ We are passionate about supporting contributors of all levels of experience and would love to see
299
+ you get involved in the project. See the
300
+ [contributing guide](https://github.com/astral-sh/uv?tab=contributing-ov-file#contributing) to get
301
+ started.
302
+
303
+ ## FAQ
304
+
305
+ #### How do you pronounce uv?
306
+
307
+ It's pronounced as "you - vee" ([`/juː viː/`](https://en.wikipedia.org/wiki/Help:IPA/English#Key))
308
+
309
+ #### How should I stylize uv?
310
+
311
+ Just "uv", please. See the [style guide](https://github.com/astral-sh/uv/blob/0.13.7/STYLE.md#styling-uv) for details.
312
+
313
+ #### What platforms does uv support?
314
+
315
+ See uv's [platform support](https://docs.astral.sh/uv/reference/platforms/) document.
316
+
317
+ #### Is uv ready for production?
318
+
319
+ Yes, uv is stable and widely used in production. See uv's
320
+ [versioning policy](https://docs.astral.sh/uv/reference/versioning/) document for details.
321
+
322
+ ## Acknowledgements
323
+
324
+ uv's dependency resolver uses [PubGrub](https://github.com/pubgrub-rs/pubgrub) under the hood. We're
325
+ grateful to the PubGrub maintainers, especially [Jacob Finkelman](https://github.com/Eh2406), for
326
+ their support.
327
+
328
+ uv's Git implementation is based on [Cargo](https://github.com/rust-lang/cargo).
329
+
330
+ Some of uv's optimizations are inspired by the great work we've seen in [pnpm](https://pnpm.io/),
331
+ [Orogene](https://github.com/orogene/orogene), and [Bun](https://github.com/oven-sh/bun). We've also
332
+ learned a lot from Nathaniel J. Smith's [Posy](https://github.com/njsmith/posy) and adapted its
333
+ [trampoline](https://github.com/njsmith/posy/tree/main/src/trampolines/windows-trampolines/posy-trampoline)
334
+ for Windows support.
335
+
336
+ ## License
337
+
338
+ uv is licensed under either of
339
+
340
+ - Apache License, Version 2.0, ([LICENSE-APACHE](https://github.com/astral-sh/uv/blob/0.13.7/LICENSE-APACHE) or
341
+ <https://www.apache.org/licenses/LICENSE-2.0>)
342
+ - MIT license ([LICENSE-MIT](https://github.com/astral-sh/uv/blob/0.13.7/LICENSE-MIT) or <https://opensource.org/licenses/MIT>)
343
+
344
+ at your option.
345
+
346
+ Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in uv
347
+ by you, as defined in the Apache-2.0 license, shall be dually licensed as above, without any
348
+ additional terms or conditions.
349
+
350
+ <div align="center">
351
+ <a target="_blank" href="https://astral.sh" style="background:none">
352
+ <img src="https://raw.githubusercontent.com/astral-sh/uv/main/assets/svg/Astral.svg" alt="Made by Astral">
353
+ </a>
354
+ </div>
355
+
@@ -0,0 +1 @@
1
+ {"key":"/usr/local","last_check":"2026-11-04T01:42:15.732142+00:00","pypi_version":"26.3"}
@@ -0,0 +1,25 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # Testing
13
+ .coverage
14
+ coverage.xml
15
+ .pytest_cache/
16
+
17
+ # IDE
18
+ .vscode/
19
+ .idea/
20
+ *.swp
21
+ *.swo
22
+
23
+ # uv
24
+ uv.lock
25
+ src/marshal_branch_manager/_version.py
@@ -0,0 +1,61 @@
1
+ image: python:3.11-slim
2
+
3
+ variables:
4
+ PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
5
+ GIT_DEPTH: 0 # Fetch full git history including tags for hatch-vcs
6
+
7
+ cache:
8
+ key: pip
9
+ paths:
10
+ - .cache/pip
11
+
12
+ stages:
13
+ - lint
14
+ - test
15
+ - build
16
+ - deploy
17
+
18
+ before_script:
19
+ - apt-get update -qq && apt-get install -y -qq git # Required for hatch-vcs
20
+ - pip install 'uv>=0.8.18'
21
+ - git fetch --tags # Ensure tags are available for hatch-vcs
22
+ - uv sync
23
+
24
+ lint:
25
+ stage: lint
26
+ script:
27
+ - uv run ruff check .
28
+ - uv run ruff format --check .
29
+ - uv run mypy src/marshal_branch_manager
30
+
31
+ test:
32
+ stage: test
33
+ script:
34
+ - uv run pytest tests/ -v --cov=marshal_branch_manager --cov-report=xml --cov-report=term
35
+ coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+)%/'
36
+ artifacts:
37
+ reports:
38
+ coverage_report:
39
+ coverage_format: cobertura
40
+ path: coverage.xml
41
+
42
+ build:
43
+ stage: build
44
+ script:
45
+ - uv build
46
+ artifacts:
47
+ paths:
48
+ - dist/*.whl
49
+ - dist/*.tar.gz
50
+
51
+ deploy:
52
+ stage: deploy
53
+ dependencies:
54
+ - build
55
+ rules:
56
+ - if: '$CI_COMMIT_TAG && $CI_COMMIT_REF_PROTECTED == "true"'
57
+ id_tokens:
58
+ PYPI_ID_TOKEN:
59
+ aud: pypi
60
+ script:
61
+ - uv publish --trusted-publishing always
@@ -0,0 +1,25 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.16.9
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+
9
+ - repo: https://github.com/pre-commit/mirrors-mypy
10
+ rev: v2.3.1
11
+ hooks:
12
+ - id: mypy
13
+ additional_dependencies: [pydantic>=2.0, cyclopts>=3.0, tomli-w>=1.0]
14
+ args: [--strict]
15
+ exclude: ^tests/
16
+
17
+ - repo: https://github.com/pre-commit/pre-commit-hooks
18
+ rev: v5.0.0
19
+ hooks:
20
+ - id: trailing-whitespace
21
+ - id: end-of-file-fixer
22
+ - id: check-yaml
23
+ - id: check-json
24
+ - id: check-toml
25
+ - id: check-merge-conflict
@@ -0,0 +1 @@
1
+ 3.11
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ - Renamed the project to `marshal-branch-manager` and the Python module to `marshal_branch_manager`. The `mbm` command, `mbm.toml` configuration, and `MBM` trailers are unchanged.
6
+ - The new distribution does not provide the `micropython-branch-manager` command. Use `mbm` instead.
@@ -0,0 +1,186 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Overview
6
+
7
+ `marshal-branch-manager` (command: `mbm`, module: `marshal_branch_manager`) is a Python CLI tool that automates maintaining a fork with multiple feature branches integrated on top of upstream. It manages rebasing integration branches with preserved merge commits, adding PRs, tracking branch metadata in TOML config, and generating GitLab MR URLs.
8
+
9
+ ## Development Commands
10
+
11
+ ### Setup
12
+ ```bash
13
+ uv sync
14
+ ```
15
+
16
+ ### Running the tool locally
17
+ ```bash
18
+ uv run mbm --help
19
+ uv run mbm init --submodule ./micropython
20
+ uv run mbm rebase # target: --target, config 'target', upstream/HEAD, upstream/master
21
+ uv run mbm add-pr 12345
22
+ uv run mbm sync <gh-username>
23
+ uv run mbm config
24
+ ```
25
+
26
+ ### Testing
27
+ ```bash
28
+ # Run all tests with coverage
29
+ uv run pytest tests/ -v --cov=marshal_branch_manager --cov-report=xml --cov-report=term
30
+
31
+ # Run specific test file
32
+ uv run pytest tests/test_specific.py -v
33
+ ```
34
+
35
+ ### Linting and Type Checking
36
+ ```bash
37
+ # Run all lint/type checks and formatting (recommended)
38
+ uv run pre-commit run --all-files
39
+
40
+ # Run ruff linter
41
+ uv run ruff check .
42
+
43
+ # Auto-fix ruff issues
44
+ uv run ruff check . --fix
45
+
46
+ # Format code
47
+ uv run ruff format .
48
+
49
+ # Type check with mypy
50
+ uv run mypy src/marshal_branch_manager
51
+ ```
52
+
53
+ ### Pre-commit Hooks
54
+ ```bash
55
+ # Install hooks
56
+ uv run pre-commit install
57
+
58
+ # Run on all files
59
+ uv run pre-commit run --all-files
60
+ ```
61
+
62
+ ### Building
63
+ ```bash
64
+ # Build wheel and sdist
65
+ uv build
66
+ ```
67
+
68
+ ## Architecture
69
+
70
+ ### Core Workflow Model
71
+
72
+ The tool supports two modes:
73
+
74
+ 1. **Config mode** - `mbm.toml` (usually in the parent repo root) holds one `[[submodules]]` entry per managed repo, each with a `path` relative to the config. The legacy flat format (top-level `path`/`submodule_path` and `[[branches]]`) still loads. User commits the config file manually.
75
+ 2. **Standalone mode** — No config file. Branch metadata is derived from git trailers in merge commit messages.
76
+
77
+ Key concepts:
78
+ - **Integration branch** — A branch (typically `main`) containing merge commits of feature branches on top of upstream
79
+ - **Feature branches** — Individual branches from upstream PRs or local development
80
+ - **Update branches** — Temporary branches created during rebase operations for GitLab MR creation
81
+ - **Branch metadata** — Stored as git trailers (`MBM-PR`, `MBM-URL`, `MBM-Author`) in merge commit messages, and optionally in TOML config
82
+
83
+ ### Module Responsibilities
84
+
85
+ - **cli.py** - CLI using cyclopts. Resolves config path (`--config` flag or `find_config()` walk-up) and the submodule (`--submodule`/`-s` selector or CWD). Resolves the rebase target.
86
+ - **config.py** - Pydantic models (`MBMConfig`, `SubmoduleConfig`, `BranchConfig`). TOML serialization via `tomllib`/`tomli-w`. Config discovery via `find_config()`.
87
+ - **git.py** - Git operations wrapper (`GitRepo` class). Includes conflict detection, rerere support (`configure_rerere`, `is_rerere_enabled`), worktree management, auto-continue rebase, upstream repo/default-branch detection (`upstream_github_repo`, `default_target`) and push remote resolution (`resolve_push_remote`).
88
+ - **trailers.py** — Git trailer support. `format_merge_message()` builds commit messages with MBM trailers. `parse_trailers_from_message()` and `extract_branches_with_metadata()` parse them back.
89
+ - **branch_sync.py** — Branch detection from merge commit subjects. Synchronizes config with detected branches.
90
+ - **rebase.py** — Orchestrates rebase workflow via `RebaseManager`. Trains rerere before rebuilding, uses trailers in merge messages, resolves remotes at runtime.
91
+ - **pr.py** — PR addition workflow via `PRManager`. Fetches PR from upstream, merges with trailers, updates config.
92
+ - **rerere.py** — `RerereTrainer` class. Trains git rerere from an existing integration branch by replaying merges in a temporary worktree.
93
+ - **github.py** — GitHub API wrapper using `gh` CLI for PR metadata lookup.
94
+ - **update_branch.py** — Update branch creation and GitLab MR URL generation.
95
+ - **exceptions.py** — Custom exceptions for git conflicts, divergence, and errors.
96
+
97
+ ### Git Operations Flow
98
+
99
+ **Rebase workflow:**
100
+ 1. Load config, resolve target (`--target`, config `target`, `upstream/HEAD`, `upstream/master`)
101
+ 2. Fetch from remotes (unless `--local`)
102
+ 3. Skip branches whose PR is merged (GitHub repo from the `upstream` remote, default `micropython/micropython`); fill missing `author` from the PR
103
+ 4. Train rerere from existing integration branch (if rerere enabled)
104
+ 5. Create update branch from target
105
+ 6. For each branch: fetch PR, rebase onto target (`--onto target <upstream default>` when target is behind upstream's default branch), merge into update branch with trailers
106
+ 7. Unless `update_feature_branches` is off: move feature branch refs, set tracking and push them to the head owner's fork
107
+ 8. Push update branch to GitLab and print the MR URL
108
+ 9. With `--apply`, reset the integration branch to the update branch
109
+
110
+ **PR addition workflow:**
111
+ 1. Parse PR identifier (number, URL, or branch name)
112
+ 2. Fetch PR metadata using `gh` CLI
113
+ 3. Create update branch from integration branch
114
+ 4. Fetch PR branch from upstream
115
+ 5. Merge PR branch with trailers in commit message
116
+ 6. Update TOML config with new branch entry
117
+ 7. Generate GitLab MR URL
118
+
119
+ ### Rerere Integration
120
+
121
+ Git rerere is configured automatically by `mbm init`. Before each rebase:
122
+ 1. A temporary worktree is created at the upstream base
123
+ 2. Each branch is merged in order, with conflicts resolved using the existing integration branch's tree
124
+ 3. rerere records each conflict resolution
125
+ 4. During the actual rebase, rerere auto-applies known resolutions
126
+ 5. If all conflicts in a step are resolved, the rebase auto-continues
127
+
128
+ ### Push Strategy
129
+
130
+ - **Feature branches** - Pushed to the remote matching the branch `author` (fork owner), or the `pr_url` owner when that URL is a fork. Never `upstream` or a remote for the upstream repo; skipped with a warning when no remote matches.
131
+ - **Integration/update branches** — Pushed to GitLab (remote detected by URL pattern)
132
+
133
+ ### Error Handling
134
+
135
+ - `RebaseConflictError` — Raised when rebase encounters unresolvable conflicts (after rerere attempt)
136
+ - `MergeConflictError` — Raised when PR merge encounters conflicts
137
+ - `RemoteDivergenceError` — Raised when remote branch has diverged from local
138
+ - `WorkingTreeDirtyError` — Raised when working tree has uncommitted changes
139
+
140
+ Conflict detection uses `git status --porcelain` to identify files with conflict markers (`UU`, `AA`, `DD` prefixes).
141
+
142
+ ## Configuration File
143
+
144
+ `mbm.toml` structure:
145
+ ```toml
146
+ # marshal-branch-manager (mbm)
147
+ # Install: pip install marshal-branch-manager
148
+ # or: uv tool install marshal-branch-manager
149
+ # Usage: mbm --help
150
+
151
+ [[submodules]]
152
+ path = "src/micropython"
153
+ integration_branch = "main"
154
+ target = "v1.27.0" # optional
155
+ update_feature_branches = true # optional
156
+
157
+ [[submodules.branches]]
158
+ name = "feature-branch-1"
159
+ pr_url = "https://github.com/micropython/micropython/pull/12345"
160
+ pr_number = 12345
161
+ title = "Add feature X"
162
+ author = "andrewleech"
163
+ ```
164
+
165
+ ## Merge Commit Trailer Format
166
+
167
+ ```
168
+ Merge branch 'feature-x'
169
+
170
+ Add feature X
171
+
172
+ MBM-PR: 12345
173
+ MBM-URL: https://github.com/micropython/micropython/pull/12345
174
+ MBM-Author: username
175
+ ```
176
+
177
+ ## Dependencies
178
+
179
+ - **pydantic** — Config models with validation
180
+ - **cyclopts** — CLI framework
181
+ - **tomli-w** — TOML writing
182
+ - **GitHub CLI (`gh`)** — PR metadata lookup (optional)
183
+
184
+ ## Testing Notes
185
+
186
+ Test files are in `tests/`. The project uses pytest with coverage reporting configured in `pyproject.toml`.