git-maintainer-tools 🧰
Small CLIs for a fork-based OSS maintainer workflow.
Homepage: github.com/kevinveenbirkenbach/git-maintainer-tools
Originally extracted from 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.
originpoints at the canonical repository.forkpoints at the maintainer's personal fork.maintracksorigin/main.remote.pushDefault=fork,push.default=currentso everygit pushand everygit push -ufor a new branch lands on the fork, not on the canonical repo.branch.main.pushRemote=originso a direct push on the canonical branch targets upstream, not the personal fork (whose branch-protection rules can diverge).
Usage:
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
~/.gnupgis unreadable) and when the working tree is dirty. - For a branch with an upstream:
git push --force-with-leaseafter any required re-sign. - For a branch without upstream:
git push -u <remote>where<remote>is resolved fromremote.pushDefault(fallback:origin). In a repo configured bygit-setup-remotes, this means new branches land on the fork.
Usage:
git-sign-push
Install 📦
From the repo checkout:
pip install .
Or for development:
pip install -e '.[dev]'
Both entry points are registered in pyproject.toml and will be on your $PATH after install.
Publish 🚀
Build sdist + wheel into dist/ and upload to PyPI:
make publish
make publish pulls in the publish extras (build, twine, keyring) automatically. Auth resolves in the following order:
- System keyring (recommended) via the
keyringpackage. Store the token once and every subsequentmake publishruns without a prompt:keyring set https://upload.pypi.org/legacy/ __token__ # enter pypi-AgEI... when prompted
~/.pypircor theTWINE_USERNAME/TWINE_PASSWORDenvironment variables (use__token__as the username and the PyPI API token as the password).
make publish-test targets TestPyPI instead; register its token under https://test.pypi.org/legacy/ in the keyring.
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
License 📜
Licensed under the MIT License.
Metadata
Release files for git-maintainer-tools 1.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| git_maintainer_tools-1.1.1.tar.gz | 11.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| git_maintainer_tools-1.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.5 kB
Release files / git_maintainer_tools-1.1.1.tar.gz
| Download URL | git_maintainer_tools-1.1.1.tar.gz |
|---|---|
| Size | 11.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2abebd08133a9c17a274ca9034e34c4c80ad016a72cde788b8e01762b47142e3
|
|
BLAKE2b-256 checksum How to use checksums |
5624e69f7ce1fa27c6a048fb6cb630d2331249d9ac2a81eb66a57d76161b5723
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / git_maintainer_tools-1.1.1-py3-none-any.whl
| Download URL | git_maintainer_tools-1.1.1-py3-none-any.whl |
|---|---|
| Size | 10.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0146cd1e53ff2bfe67b029baf109024c81be07165e8f74234358b870bd0a1f26
|
|
BLAKE2b-256 checksum How to use checksums |
18879535ce6cb4b0b4a76f92e499ae3efd2286772489fc8439618151c0feb27e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|