{"id":49824832,"url":"https://github.com/bucketgit/bgit","last_synced_at":"2026-05-30T07:02:42.914Z","repository":{"id":357200299,"uuid":"1235743340","full_name":"bucketgit/bgit","owner":"bucketgit","description":"bgit CLI - BucketGit serverless git stack","archived":false,"fork":false,"pushed_at":"2026-05-29T16:20:05.000Z","size":917,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-29T18:05:24.242Z","etag":null,"topics":["aws","gcp","git","help-wanted","serverless"],"latest_commit_sha":null,"homepage":"https://bucketgit.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bucketgit.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-11T16:00:13.000Z","updated_at":"2026-05-28T20:12:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/bucketgit/bgit","commit_stats":null,"previous_names":["bucketgit/bgit"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/bucketgit/bgit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bucketgit%2Fbgit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bucketgit%2Fbgit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bucketgit%2Fbgit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bucketgit%2Fbgit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bucketgit","download_url":"https://codeload.github.com/bucketgit/bgit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bucketgit%2Fbgit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33682998,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","gcp","git","help-wanted","serverless"],"created_at":"2026-05-13T15:01:02.161Z","updated_at":"2026-05-30T07:02:42.908Z","avatar_url":"https://github.com/bucketgit.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bgit\n\n`bgit` is a Git CLI for repositories stored directly in cloud buckets. It keeps\nnormal `.git` checkouts on disk, so developers can use familiar local Git\nworkflows, while BucketGit stores repository objects and refs in GCS or S3 and\ncoordinates access through a lightweight broker.\n\nUse it when you want Git repositories in cloud object storage without running a\nGit server.\n\n## Project\n\n- Homepage: https://bucketgit.com/\n- Author: Dennis Vink\n- License: MIT\n\n## Install\n\nWith Homebrew:\n\n```bash\nbrew tap bucketgit/bgit\nbrew install bgit\n```\n\nOr build from source:\n\n```bash\ngit clone https://github.com/bucketgit/bgit.git\ncd bgit\ngo build -o bgit .\n```\n\nCheck the installed version:\n\n```bash\nbgit --version\n```\n\n## How BucketGit Works\n\nBucketGit has two layers:\n\n- A normal local Git checkout on your machine.\n- A broker-backed repository stored directly in GCS, S3, or a local broker\n  object backend.\n\nThe broker handles repository mapping, roles, SSH-key authorization, pull\nrequests, issues, branch protection, and short-lived object-transfer\ncapabilities. Developers do not need long-lived bucket credentials for everyday\nclone, fetch, pull, push, review, or web browsing flows.\n\nDirect bucket access still exists under `bgit direct` for recovery, migration,\nand low-level inspection. It is not the normal user workflow.\n\n![BucketGit serverless architecture](architecture/bucketgit-serverless-architecture.png)\n\n## Quickstart\n\nSet up BucketGit for one or more cloud profiles:\n\n```bash\nbgit setup\n```\n\n`bgit setup` is the interactive broker setup and management tool. It discovers\nGCP and AWS profiles, lets you choose regions, creates or updates brokers,\nimports owner SSH keys, manages users and teams, and writes global configuration\nto `~/.bgit/config.yaml`. Set `BGIT_HOME` to use another BucketGit config\ndirectory.\n\nFor local hosting, `bgit clone file://repo.git`, `bgit clone s3://repo.git`,\nand `bgit clone gs://repo.git` create or attach a broker-backed repository\nwithout deploying cloud broker infrastructure. The local broker is part of the\n`bgit` binary and stores broker metadata with the repository in the reserved\n`.bucketgit/broker-state/` namespace.\n\nLocal broker repository URLs select the backing storage:\n\n```bash\nbgit clone file://app.git\nbgit clone s3://app.git --profile work --region eu-west-1\nbgit clone gs://app.git --profile work --region europe-west1\n```\n\n`file://` repositories are stored below `~/.bgit/local-broker` or\n`$BGIT_HOME/local-broker`. `s3://` and\n`gs://` repositories use one cloud bucket per repository, named from the cached\nAWS account ID or GCP project ID plus the repo name, for example\n`123456789012-app`. The visible repository name remains `app.git`. If\n`--profile` or `--region` is omitted, BucketGit uses `default` plus the\nprovider's default region (`us-east-1` for AWS, `us-central1` for GCP).\n\nCreate a broker repository, then attach a local checkout:\n\n```bash\nbgit admin repo create --team core demo\nmkdir demo\ncd demo\nbgit init\n\necho \"hello\" \u003e README.md\nbgit add README.md\nbgit commit -m \"Initial commit\"\nbgit push\n```\n\nClone an existing broker-backed repository:\n\n```bash\nbgit clone https://broker.example.com/demo.git ./demo\n```\n\nFlat clone URLs use the broker's default `core` team. The explicit form is also\naccepted:\n\n```bash\nbgit clone https://broker.example.com/core/demo.git ./demo\nbgit clone https://broker.example.com/core/demo/demo.git ./demo\n```\n\nInside an initialized checkout, normal Git commands also work for fetch and push\nthrough the `core.sshCommand` written by `bgit init`:\n\n```bash\ngit fetch\ngit push\n```\n\n## Custom Domains\n\nBucketGit can discover brokers from DNS TXT records, so users can clone from a\nclean domain instead of a generated Cloud Run or Lambda Function URL.\n\nFor `https://git.example.com/...`, publish records at `_bgit.git.example.com`.\nDiscovery is exact-FQDN based; BucketGit does not fall back from\n`git.example.com` to `example.com`.\n\n```text\nv=bgit1 broker=https://broker.example.com team=t_abcd1234 name=platform\n```\n\nThe `name` is the public path segment users type. The `team` value is the\nopaque broker team identifier. With the record above, both forms work:\n\n```bash\nbgit clone https://git.example.com/platform/demo.git ./demo\nbgit clone https://git.example.com/platform/demo/demo.git ./demo\n```\n\nBucketGit skips TXT discovery for direct broker URLs such as Cloud Run and AWS\nLambda Function URLs.\n\n## Common Commands\n\n```bash\nbgit setup\nbgit setup profile create --provider gcp work\nbgit setup profile create --provider aws work\n\nbgit admin repo create --team core demo\nbgit init\nbgit init --noninteractive --repo demo --profile work.europe-west1 --team core\nbgit clone https://broker.example.com/demo.git ./demo\nbgit web\n\nbgit status\nbgit add -A\nbgit commit -m \"Update\"\nbgit checkout -b feature/docs\nbgit diff\nbgit log --oneline\n\nbgit fetch\nbgit pull\nbgit push\nbgit push --tags\nbgit push --delete feature/docs\nbgit ls-remote\n\nbgit pr create --title \"Add docs\" --source feature/docs --target main\nbgit pr list\nbgit pr view 1\nbgit pr diff 1\nbgit pr merge 1\n\nbgit board list\nbgit board create \"As a maintainer, I want clear setup docs so that new users can bootstrap quickly.\"\nbgit board take BG-1\nbgit board move BG-1 doing\nbgit board comment BG-1 \"Opened PR #2.\"\n\nbgit issue create \"Bug report\" --body \"Details\"\nbgit issue list\nbgit issue view 1\n\nbgit ci run --ref feature/docs\nbgit ci list\nbgit ci view 1\nbgit ci logs 1\nbgit ci watch 1\n\nbgit whoami\nbgit repos mine\n\nbgit admin repo list\nbgit admin repo info\n```\n\n## Setup And Broker Management\n\nGlobal configuration is stored in `~/.bgit/config.yaml`, or\n`$BGIT_HOME/config.yaml` when `BGIT_HOME` is set. Profiles are\nprovider- and region-aware, so the same cloud account can have brokers in\nmultiple regions.\n\nExamples:\n\n```bash\nbgit admin repo create --team core app\nbgit init --noninteractive --repo app --profile work.europe-west1 --team core\nbgit push --profile work --region europe-west1\n```\n\nIf a profile has multiple configured regions, pass the region explicitly:\n\n```bash\nbgit push --profile work --region eu-west-1\n```\n\nor use a region-qualified profile name:\n\n```bash\nbgit push --profile work.eu-west-1\n```\n\n`bgit setup` can also create cloud CLI profiles:\n\n```bash\nbgit setup profile create --provider gcp work\nbgit setup profile create --provider aws work\n```\n\nGCP setup uses `gcloud` configurations and can deploy the broker and CI\nmaterializer into Cloud Run/Cloud Build backed infrastructure. AWS setup reads\nAWS config/credentials files and can use the AWS CLI when profile creation is\nrequested; it deploys the broker stack, Lambda materializer handoff, CodeBuild\nintegration, and broker-managed secrets.\n\nLocal broker repositories use the same broker authorization and ref-safety\nmodel without deploying a shared broker. Repository metadata is persisted under\n`.bucketgit/broker-state/`. Ref updates are committed through per-ref broker\nstate records and short lock files, then materialized back to normal Git ref\nfiles.\n\nCloud-backed local broker repositories use cached profile metadata from\nthe global BucketGit config for deterministic bucket naming. `bgit setup profile\ncreate --provider aws NAME` records the AWS account ID for a profile, and\n`bgit setup profile create --provider gcp NAME` records the GCP project ID. If\nan existing AWS or GCP CLI profile is used before it is cached, BucketGit imports\nthat account/project ID once and then reuses the cached value.\n\n`bgit setup` also manages configured brokers. From the setup UI you can create,\nupdate, manage, or delete brokers, manage users and teams, and seed the default\n`core` team. Repositories are created explicitly with `bgit admin repo create`\nor through the setup broker-management UI; `bgit init` asks for the repository\nname when needed and attaches the checkout to that broker repository.\n\nBroker setup uses one-time owner bootstrap tokens. The deployed broker stores a\ntoken hash, not a readable token, and marks the bootstrap as used after the\nowner key is imported. If an old broker rejects newer signed requests, upgrade\nit from an attached repository:\n\n```bash\nbgit admin broker upgrade\nbgit admin broker owner-bootstrap reset\n```\n\n## Identity\n\nBucketGit supports a global name and email in the global BucketGit config and per-repo\nidentity in `.git/config`, matching the way Git users expect identity to work.\nThe repo-local identity overrides the global one.\n\nIf no identity is configured, BucketGit falls back to a default client identity\nand warns before pushing.\n\n## Access Control\n\nRepository access is broker-backed and SSH-key based. Roles are:\n\n- `owner`\n- `admin`\n- `maintainer`\n- `developer`\n- `triage`\n- `read`\n\nOwners cannot be deleted or suspended. Ownership transfer uses a two-step flow:\nthe current owner creates a transfer command, and the new owner accepts it with\nan SSH signature.\n\nBroker users are stable broker identities with SSH keys. Repository access can\ncome from direct repository grants, team membership plus team-to-repository\ngrants, or invite flows when explicit acceptance is required. Broker admins can\nassign existing broker users directly through setup; repo admins can use the\nrepo-scoped access flows available to their role.\n\nUseful admin commands:\n\n```bash\nbgit admin repo list\nbgit admin repo info\nbgit admin repo create --team platform app\nbgit admin broker upgrade\nbgit admin broker owner-bootstrap reset\n\nbgit admin keys list\nbgit admin keys add --user ada --role developer --key ~/.ssh/ada.pub\nbgit admin keys import-github octocat --role triage\nbgit admin keys suspend KEY_OR_FINGERPRINT\nbgit admin keys remove KEY_OR_FINGERPRINT\n\nbgit admin invite-user --broker https://broker.example.com --user ada --role developer demo.git\nbgit admin accept-invite CODE\nbgit admin cancel-invite --broker https://broker.example.com --user ada demo.git\n\nbgit admin invite-broker-user --broker https://broker.example.com --user ada --role user\nbgit admin accept-broker-invite CODE\nbgit admin cancel-broker-invite --broker https://broker.example.com --user ada\n\nbgit admin confirm-ownership-transfer --broker https://broker.example.com demo.git\nbgit admin accept-ownership-transfer CODE\nbgit admin cancel-ownership-transfer --broker https://broker.example.com demo.git\n\nbgit admin protect add main\nbgit admin protect list\nbgit admin protect remove main\nbgit admin ci rotate-secret\n\nbgit admin broker-users list\nbgit admin broker-users upsert ada --role user --key ~/.ssh/ada.pub\nbgit admin broker-users upsert ada --role user --suspended true\nbgit admin broker-users delete ada\n\nbgit admin teams create platform\nbgit admin teams delete TEAM_ID\nbgit admin teams member add TEAM_ID ada --role developer\nbgit admin teams member remove TEAM_ID ada\nbgit admin teams repo list\nbgit admin teams repo add TEAM_ID developer\nbgit admin teams repo remove TEAM_ID\n```\n\nA repo can have at most one active pending invite per username. Invite\ncancellation is repo-scoped. Broker logical repository names are flat, such as\n`demo.git`; path-shaped clone URLs route through teams. Flat broker clone URLs\nuse the default `core` team, while `bgit init` prompts for a team or requires\n`--team` in noninteractive mode.\n\nBroker requests use replay-resistant v2 SSH signatures over method, path, host,\ntimestamp, nonce, and payload hash. Older brokers that do not understand these\nsignatures should be upgraded before using newer clients.\n\n## Repository Settings\n\nBroker-backed repositories support public/private visibility, read-only mode,\nissues, branch protection, logical rename, and owner-only destructive delete.\n\n```bash\nbgit admin repo visibility public\nbgit admin repo visibility private\nbgit admin repo readonly on\nbgit admin repo readonly off\nbgit admin repo issues on\nbgit admin repo issues off\nbgit admin repo rename new-name\nbgit admin repo delete --yes\n```\n\nPublic repositories can be cloned and browsed without an SSH key. Private\nrepositories require a recognized broker SSH key.\n\n## Pull Requests And Issues\n\nPull requests and issues are broker metadata, not part of the Git protocol.\nBucketGit implements them on top of repository refs and broker-side metadata.\n\n```bash\nbgit pr create --title \"Add docs\" --source feature/docs --target main\nbgit pr list\nbgit pr view 1\nbgit pr diff 1\nbgit pr comment 1 \"Looks good\"\nbgit pr approve 1 \"Approved\"\nbgit pr reject 1 \"Please change this\"\nbgit pr merge 1 --delete-branch\nbgit pr close 1\n\nbgit issue create \"Missing docs\" --body \"The setup page needs examples.\"\nbgit issue list\nbgit issue comment 1 \"I can take this.\"\nbgit issue close 1\nbgit issue reopen 1\n```\n\nBranch protection is enforced by the broker. Protected branches can require the\nPR merge path, with optional owner/admin override.\n\n`bgit web` also has a pull-request creation flow with base/compare branch\nselection, diff preview, and mergeability/conflict status before creating the\nPR.\n\n## Task Board\n\nBroker-backed repositories have a task board immediately; no board creation is\nrequired. Stories are stored in repository metadata and move through\n`backlog`, `ready`, `doing`, `review`, and `done`. Viewers can read the board;\ndevelopers and higher can create stories, take or reassign work, move cards, and\ncomment.\n\n```bash\nbgit board list\nbgit board create \"As a developer, I want CI logs on each run so that failures are easy to diagnose.\"\nbgit board take BG-1\nbgit board move BG-1 review\nbgit board comment BG-1 \"PR #4 is ready for review.\"\n```\n\nStory IDs are prefixed with a repository monogram. The web board supports\ndrag-and-drop lane moves, assignment controls, comments, optimistic committing\nstate, and an \"Only me\" filter for assigned work.\n\n## CI/CD\n\nBucketGit stores CI run records in the broker and hands builds to the trusted\ncloud provider/materializer path for a broker ref and commit. The broker\nverifies repository state before queueing CI so clients cannot upsert arbitrary\nbuild payloads without corresponding Git state.\n\n```bash\nbgit ci list\nbgit ci run --ref feature/docs\nbgit ci run --ref feature/docs --config cloudbuild.yaml --provider gcp\nbgit ci run --ref feature/docs --config buildspec.yaml --provider aws\nbgit ci view 1\nbgit ci logs 1\nbgit ci watch 1\n```\n\nGCP builds use Cloud Build configuration such as `cloudbuild.yaml`. AWS builds\nuse CodeBuild configuration such as `buildspec.yaml`. Provider-specific\nalternate YAML filenames can be passed with `--config`.\n\nCI materializer tokens are broker-managed secrets. Rotate them with:\n\n```bash\nbgit admin ci rotate-secret\n```\n\n## Web UI\n\n`bgit web` serves a local browser UI on `127.0.0.1:8042`:\n\n```bash\nbgit web\n```\n\nThe web UI uses the configured repository and broker by default. It shows files,\ncommits, pull requests, issues, the task board, CI runs and logs, repository\nsettings, user profile settings, capability-aware controls, local\ndirty/staged/unpushed state, and remote sync status.\n\nUse local-only mode to browse the local `.git` object store without broker\nrefreshes:\n\n```bash\nbgit web --local\nbgit web --port 9000\n```\n\nUser profile settings include bio, SSH-key display, avatar upload, drag-to-pan\ncropping, and zoom controls. Local web mutations are protected with CSRF tokens.\n\nThe web assets are embedded into the `bgit` binary at build time.\n\n## Native Git Transport\n\n`bgit init` writes a Git remote like:\n\n```text\ngit@git.bucketgit.com:demo.git\n```\n\nand configures:\n\n```text\ncore.sshCommand=bgit ssh\n```\n\nThat lets native Git use BucketGit for fetch and push inside initialized\nrepositories:\n\n```bash\ngit fetch\ngit push\n```\n\nNative Git transport is authorized through the broker. Ref updates use\ncompare-and-swap checks so stale writers are rejected instead of silently\noverwriting refs.\n\n## Direct Bucket Mode\n\nDirect bucket mode is the low-level escape hatch for recovery, migration,\nscripts, and debugging. It uses cloud credentials directly and bypasses the\nnormal broker-first workflow.\n\n```bash\nbgit direct help\nbgit direct clone gs://bucket/repositories/demo.git\nbgit direct clone s3://bucket/repositories/demo.git\nbgit direct fetch\nbgit direct push\nbgit --bucket my-bucket --prefix repositories/demo.git direct ls docs/\nbgit --bucket my-bucket --prefix repositories/demo.git direct cat docs/readme.md\n```\n\nCloud IAM and bucket-policy recovery commands also live under direct mode:\n\n```bash\nbgit direct admin grant-read user:dev@example.com\nbgit direct admin grant-write serviceAccount:ci@project.iam.gserviceaccount.com\nbgit direct admin grant-admin arn:aws:iam::123456789012:role/Admin\n```\n\n## Broker Maintenance\n\nBroker maintenance commands are intentionally separated from normal user flows:\n\n```bash\nbgit janitor members reindex\nbgit broker delete --provider gcp --profile work --region europe-west1 --yes\nbgit broker delete --provider aws --profile work --region eu-west-1 --yes\n```\n\nUse them for repair, test cleanup, or broker decommissioning.\n\n## Development And Tests\n\nBuild from source:\n\n```bash\ngo build -o bgit .\n```\n\nRun unit tests:\n\n```bash\ngo test ./...\n```\n\nRun the local broker integration suite:\n\n```bash\n./testsuite/run-local-broker.sh gcp\n./testsuite/run-local-broker.sh aws\n```\n\nThe integration suite uses local object storage and fake provider clients for\nGCP and AWS. It does not require cloud credentials or deployed brokers.\n\n## Requirements\n\nRuntime requirements depend on the command:\n\n- `git` on `PATH` for repository initialization and native Git compatibility.\n- `ssh-agent`/`ssh-add` for broker SSH-key signing flows.\n- `gcloud` for GCP setup and profile creation.\n- AWS config/credentials files and optionally the AWS CLI for AWS setup/profile\n  creation.\n- Go 1.22 or newer to build from source.\n\n## Unsupported Commands\n\nBucketGit implements the supported local workflow commands directly. Commands\noutside that subset return an unsupported-command error instead of delegating to\nthe system Git binary.\n\nUnsupported commands include repository maintenance and server features such as\n`daemon`, `submodule`, `lfs`, `gc`, `fsck`, `repack`, `prune`, `worktree`,\ncredential helpers, and related server helpers.\n\n## Contributing\n\nContributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for the\nfork-to-pull-request workflow and the checks to run before opening a PR.\n\n## License\n\n`bgit` is released under the MIT License. See [LICENSE](LICENSE).\n\n## Disclaimer\n\n`bgit` is provided as-is, without warranty of any kind. You are responsible for\ntesting it against your own repositories, access controls, backup strategy, and\noperational requirements before relying on it in production.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbucketgit%2Fbgit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbucketgit%2Fbgit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbucketgit%2Fbgit/lists"}