Git Integration Guide
Overview
GitBucket.WTF stores git repositories directly in object storage (S3-compatible, Vercel Blob, or local FS) — there's no relational database in the path. Both clients use a shared engine (@gitbucket/storage's GitEngine) so the on-disk layout is identical no matter which one wrote it.
Two client paths:
- HTTP Smart Protocol — standard
gitagainst the Next.js app. Use this when you wantgit clone https://.../git pushto work unchanged. gibCLI — direct-to-bucket, no server. Use this for CI/CD, air-gapped setups, or platform-free workflows. See CLI.md.
Architecture
Storage Structure
Git objects are stored in the bucket following the standard Git object model:
{prefix}/ # e.g. repos/{orgId}/{repoId}/ for the web app,
├── HEAD # or any user-chosen path for gib
├── objects/
│ ├── {hash[0:2]}/
│ │ └── {hash[2:]} # loose objects (header + content, no compression)
│ └── pack/
│ ├── pack-{sha}.pack # downloaded by gib clone/pull
│ └── pack-{sha}.idx
├── refs/
│ ├── heads/
│ │ └── {branchName} -> commit hash
│ └── tags/
│ └── {tagName} -> commit hash
HEAD is a symbolic ref (ref: refs/heads/<default-branch>\n) so the engine can determine the default branch without needing a separate config file.
Git HTTP Smart Protocol
GitBucket.WTF implements the Git HTTP Smart Protocol endpoints:
-
Info/Refs (
GET /api/git/:orgSlug/:repoSlug/info/refs?service=git-upload-pack)- Returns available refs (branches, tags)
- Used by
git cloneandgit fetch
-
Upload Pack (
POST /api/git/:orgSlug/:repoSlug/git-upload-pack) - TODO- Handles object transfer for clone/fetch operations
-
Receive Pack (
POST /api/git/:orgSlug/:repoSlug/git-receive-pack) - TODO- Handles object transfer for push operations
Usage
Path A — standard git over HTTPS (web app)
git clone https://gitbucket.wtf/api/git/myorg/myrepo.git
git remote add origin https://gitbucket.wtf/api/git/myorg/myrepo.git
git push origin main
git pull origin main
Path B — direct to bucket with gib
# From inside any git repo
gib remote add origin s3://my-bucket/repos/myorg/myrepo
gib push origin main
gib status # see what's ahead/behind
gib clone s3://my-bucket/repos/myorg/myrepo ./fresh-clone
See CLI.md for the full surface, storage URL formats, and the gib status state legend.
Configuration
Each organization configures its own S3/Storj credentials:
- Go to Organization Settings
- Configure S3 endpoint, bucket, region, and credentials
- All repositories under that organization use these credentials
Implementation Status
- ✅ Shared
GitEnginein@gitbucket/storage(one engine, two clients) - ✅ Pluggable storage adapters (S3-compatible, Vercel Blob, local FS)
- ✅ Loose object + ref read/write
- ✅ Pack data plane (
storePack/listPacks/getPack) — CLI uses it on download - ✅
gibCLI: init, remote, push, pull, clone, status - ✅ Info/Refs / Upload Pack / Receive Pack HTTP smart-protocol routes
- 🚧 Pack-on-push for the CLI (data plane ready; blocked on server-side pack reads)
- 🚧 Server-side pack-aware reads in
GitEngine.getObject(needed before pack-on-push is safe)
Future Enhancements
- SSH support
- Web hooks
- Branch protection rules enforcement
- Large file support (Git LFS)
- Shallow clone support