git-buckets
gb is the end-user CLI for a git-buckets deployment: git repos and Python package indexes over HTTPS, backed by S3.
Someone else runs the deployment. You log in once and then use stock git and uv.
Install
Prereqs:
- git (≥ 2.13, ≥ 2.40 for bundle-accelerated clones)
- git-lfs
- Python ≥ 3.14
uv tool install git-buckets
# or: pipx install git-buckets
First login
gb login git.example.com
Once per deployment, never per bucket. This signs you in through the browser, stores the session, writes the
credential-helper stanza for https://*.git.example.com plus transfer.bundleURI = true into your global gitconfig,
and records the deployment.
On a box with no browser, --no-browser prints a URL to open elsewhere and reads the code back at a masked prompt.
gb auth status # deployments known, the user on each, where each secret lives
gb logout git.example.com # revoke the session token, erase the stored credentials
Daily use
Remote URLs are https://<bucket>.<deployment-domain>/<repo>: the first hostname label is the bucket's public label,
the path is the repo name, as deep as you like. git clone https://my-bucket.git.example.com/tools/cli/my-project, then
fetch, pull and push are stock git as well.
New repos are made by pushing. There is no create command, simply push to a new path on an existing bucket and you've created a new repo.
git init && git remote add origin https://my-bucket.git.example.com/tools/gui/my-new-project
git push -u origin main
Signed commits. Buckets require them by default: every commit a push introduces is checked, so set up signing before
the first push (gpg.format ssh + user.signingkey + commit.gpgsign is the short route).
LFS. Downloads at any size and uploads up to 5 GB per file need nothing installed: objects come from the same host under the same credential. Above 5 GB an upload needs gb's transfer agent, which also makes both directions parallel and resumable. Once per repo:
gb lfs install [--remote <name>]
Packages. Each bucket is one Python index. In the consuming project's pyproject.toml:
[[tool.uv.index]]
name = "my-bucket-index"
url = "https://gb@my-bucket.git.example.com/packages/pypi/"
explicit = true
[tool.uv.sources]
my-package = { index = "my-bucket-index" }
[tool.uv]
keyring-provider = "subprocess"
Then just uv sync as normal. The gb@ is required: uv only does keyring discovery when the index URL carries a
username.
Publishing needs one more line on the index, in the publishing project rather than the consuming one, naming the repo the package belongs to:
[[tool.uv.index]]
name = "my-bucket-index"
url = "https://gb@my-bucket.git.example.com/packages/pypi/"
publish-url = "https://gb@my-bucket.git.example.com/packages/pypi/upload/tools/cli/my-project/"
explicit = true
Then uv build && uv publish --index my-bucket-index. Push rights are publish rights: the repo in the upload URL is the
one your token must reach with rw.
CI. A runner has no login session: it assumes the team's token role via OIDC and sets
UV_KEYRING_PROVIDER=subprocess and GB_KEYRING_HOSTS="*.git.example.com". GB_KEYRING_HOSTS is CI only, never needed
on a user machine.
Repo lifecycle
Every subcommand takes <bucket>/<repo>, plus -H/--host <domain> when more than one deployment is registered.
gb repo list
gb repo info my-bucket/tools/cli/my-project # head, refs, size, last push; -v lists every ref
gb repo protect my-bucket/tools/cli/my-project main # blocks delete while the ref exists
gb repo unprotect my-bucket/tools/cli/my-project main
gb repo delete my-bucket/tools/cli/my-project --yes # without --yes it only prints what would go
Delete takes the repo's LFS objects, locks, bundles, packages and rendered web tree with it. The undo path is S3
versioning on the operator's side, not a gb command. There is no rename.
Where the secrets live
The refresh token (one year, fixed from sign-in) goes in your OS keyring, or in ~/.config/gb/hosts.yml at 0600 when no
keyring works: gb says which, once. On a headless Linux box, pass + gpg-agent is the supported keyring. The hourly ID
and session tokens are just caches under ~/.local/state/gb/<domain>/.
Troubleshooting
- git prompts for a username and password: the host isn't registered.
gb auth status, thengb login. the session for <domain> has expired: the refresh token is past its year, or was revoked. Log in again.- A push is refused but a fetch works: your grant on that prefix is read-only.
- A package index won't authenticate:
GB_KEYRING_DEBUG=1 uv syncprints why the keyring backend declined.
Release files for git-buckets 0.3.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_buckets-0.3.1.tar.gz | 35.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| git_buckets-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 79.8 kB
Release files / git_buckets-0.3.1.tar.gz
| Download URL | git_buckets-0.3.1.tar.gz |
|---|---|
| Size | 35.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
83bdd73544a8ce986f71494424552a5115aac8766e36ceac9f35436259c6cf32
|
|
BLAKE2b-256 checksum How to use checksums |
90c37b1c6ce82f94f52bd7d00aa7e042c6277de06b7643ce689302f7d69b5604
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.
Transparency logRelease files / git_buckets-0.3.1-py3-none-any.whl
| Download URL | git_buckets-0.3.1-py3-none-any.whl |
|---|---|
| Size | 44.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
19f89e397d41e56b0798ae83d5c6fae8527b98494e04ee4dc99324b4336c90d3
|
|
BLAKE2b-256 checksum How to use checksums |
777ff8fde999e56ce5f3156355631f65871e0c2cd06be8d301098e585acdf6da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.
Transparency log