Ship the two maintainer workflow helpers as installable Python CLIs so
any fork-based OSS project can reuse them without vendoring shell
scripts:
* git-setup-remotes configures origin/fork/main-tracking/pushDefault
for a fork-based clone. URLs are parameterized (--canonical / --fork
or CANONICAL_URL / FORK_URL) so the same binary bootstraps any
maintainer's repo. Idempotent.
* git-sign-push GPG-signs every unpushed commit on the current branch
and pushes, resolving the target remote from remote.pushDefault
(falling back to origin) for branches without upstream.
Both refuse to run when CLAUDE_CODE/CLAUDECODE is set, since the Claude
sandbox blocks .git/config writes and access to ~/.gnupg: failing fast
beats failing late.
Other additions:
* Makefile: install / install-dev / test / lint / clean targets.
* .github/workflows/test.yml: pytest + ruff matrix for py 3.10/11/12.
* MIRRORS: github, git.veen.world:2201, code.infinito.nexus:2201, pypi.
* LICENSE switched to MIT; README records the extraction origin
(s.infinito.nexus/code) and adds author + license sections.
* Tests cover sandbox-refusal guards and the fork-URL resolution
preference order (CLI arg > env var > existing fork remote > origin
when not canonical).
73 lines
2.9 KiB
Markdown
73 lines
2.9 KiB
Markdown
# git-maintainer-tools 🧰
|
|
[](https://github.com/sponsors/kevinveenbirkenbach) [](https://www.patreon.com/c/kevinveenbirkenbach) [](https://buymeacoffee.com/kevinveenbirkenbach) [](https://s.veen.world/paypaldonate)
|
|
|
|
|
|
Small CLIs for a fork-based OSS maintainer workflow.
|
|
|
|
Homepage: [github.com/kevinveenbirkenbach/git-maintainer-tools](https://github.com/kevinveenbirkenbach/git-maintainer-tools)
|
|
|
|
Originally extracted from [s.infinito.nexus/code](https://s.infinito.nexus/code), where these helpers started as shell scripts under `scripts/git/` before being rewritten in Python and split out as a standalone tool.
|
|
|
|
## Tools 🔧
|
|
|
|
### `git-setup-remotes` 🌐
|
|
|
|
Configures a clone for a fork-based workflow and is idempotent.
|
|
|
|
- `origin` points at the canonical repository.
|
|
- `fork` points at the maintainer's personal fork.
|
|
- `main` tracks `origin/main`.
|
|
- `remote.pushDefault` = `fork`, `push.default` = `current` so every `git push` and every `git push -u` for a new branch lands on the fork, not on the canonical repo.
|
|
|
|
Usage:
|
|
|
|
```bash
|
|
git-setup-remotes \
|
|
--canonical git@github.com:<org>/<repo>.git \
|
|
--fork git@github.com:<user>/<fork>.git
|
|
```
|
|
|
|
Both URLs may be provided via environment variables instead (`CANONICAL_URL`, `FORK_URL`). If `--fork` / `FORK_URL` is not given, the tool reuses an existing `fork` remote or an existing `origin` that does not point at canonical (clone-from-fork case).
|
|
|
|
### `git-sign-push` 🔐
|
|
|
|
GPG-signs every unpushed commit on the current branch and pushes.
|
|
|
|
- Refuses to run inside the Claude sandbox (where `~/.gnupg` is unreadable) and when the working tree is dirty.
|
|
- For a branch with an upstream: `git push --force-with-lease` after any required re-sign.
|
|
- For a branch without upstream: `git push -u <remote>` where `<remote>` is resolved from `remote.pushDefault` (fallback: `origin`). In a repo configured by `git-setup-remotes`, this means new branches land on the fork.
|
|
|
|
Usage:
|
|
|
|
```bash
|
|
git-sign-push
|
|
```
|
|
|
|
## Install 📦
|
|
|
|
From the repo checkout:
|
|
|
|
```bash
|
|
pip install .
|
|
```
|
|
|
|
Or for development:
|
|
|
|
```bash
|
|
pip install -e '.[dev]'
|
|
```
|
|
|
|
Both entry points are registered in `pyproject.toml` and will be on your `$PATH` after install.
|
|
|
|
## Sandbox 🏜️
|
|
|
|
Both CLIs refuse to run when `CLAUDE_CODE` or `CLAUDECODE` is set in the environment, because the Claude sandbox blocks `.git/config` writes (for `git-setup-remotes`) and access to `~/.gnupg` (for `git-sign-push`). The tools MUST be run by the human operator outside the sandbox.
|
|
|
|
## Author ✍️
|
|
|
|
Kevin Veen-Birkenbach, [veen.world](https://www.veen.world/)
|
|
|
|
## License 📜
|
|
|
|
Licensed under the [MIT License](LICENSE).
|