gitcaskDocsGitHub

API

Every gitcask instance serves git, LFS and a JSON API for every repository under that repository's own path.

One prefix per repository

Everything for a repository starts with /{owner}/{repo}, so a proxy routes on the first two path segments alone.

/{owner}/{repo}
/info/refs/git-upload-pack/git-receive-pack/info/lfs/…/api/…/api-browser/…
The repository prefix /{owner}/{repo} leads to git smart HTTP, LFS, the api lane and the api-browser lane.
LanePrefixFor
Direct/{owner}/{repo}/apiServers and CLIs
Browser/{owner}/{repo}/api-browserSame handlers; CORS only for server.cors_origins
Reference/docsScalar UI over /openapi.json
Discovery/api/v1Not tied to a repository

Git and LFS

Standard git and git-lfs clients work unchanged. Paths are relative to the repository prefix.

RoutePurpose
GET /info/refsRef advertisement
POST /git-upload-packClone and fetch
POST /git-receive-packPush
POST /info/lfs/objects/batchLFS batch
GET HEAD PUT /info/lfs/objects/{oid}LFS basic transfer
POST /info/lfs/verifyLFS verify
SurfaceSupported
ProtocolSmart HTTP v0 and v2
Fetchls-refs with prefixes, filter, shallow, deepen, sideband-all
Pushatomic, delete, tags, push options, report-status-v2

Reads

Reads need the read scope. Paths are relative to the repository prefix.

RoutePurpose
GET /apiRepository summary
GET /api/refsGet the default ref
GET /api/refs/{kind}List branches or tags; query prefix, q, after, n
GET /api/resolveResolve the default ref
GET /api/resolve/{rest}Resolve a revision and optional path
GET /api/tree/{rest}Browse a tree
GET /api/blob/{rest}Read a blob; inline up to 2 MiB, raw for text/plain
GET /api/commitsList commits
GET /api/commit/{sha}Get commit details
GET /api/compare/{base}...{head}Compare two revisions
GET HEAD /api/archive/{archive_ref}Download an immutable repository archive

Writes

Writes need the write scope. A stale expected_old_oid, expected_head_oid or expected_base_oid returns 409.

RoutePurpose
PUT /api/refs/heads/{name}Create or move a branch; body target, optional expected_old_oid
DELETE /api/refs/heads/{name}Delete a branch; optional ?expected_old_oid=
PUT /api/refs/tags/{name}Create or move a lightweight tag
DELETE /api/refs/tags/{name}Delete a tag
POST /api/tagsCreate an annotated tag
POST /api/commitsCommit a batch of file changes
POST /api/mergesMerge one revision into a branch: merge, squash or fast-forward-only; expected_base_oid required
POST /api/initializeInitialize a pristine repository from a pinned Gitcask tree
POST /api/import/resolvePin a full-history import source
POST /api/importImport pinned complete history into a pristine repository
GET /api/import/receiptRead a committed import receipt

Commit without a clone

One request writes blobs, trees and a commit, then moves the branch through the WAL. Replace expected_head_oid with the branch's current oid; content is standard base64.

curl -fsS -X POST http://127.0.0.1:8080/acme/web/api/commits \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d @- <<'JSON'
{
  "branch": "main",
  "message": "Update the readme",
  "expected_head_oid": "<current oid of main>",
  "committer": { "name": "CI", "email": "ci@example.com", "when": "2026-10-07T09:00:00Z" },
  "changes": [
    { "op": "upsert", "path": "README.md", "content": "IyBXZWIK", "mode": "100644" },
    { "op": "rename", "from": "docs/old.md", "to": "docs/new.md" },
    { "op": "delete", "path": "tmp/scratch.txt" }
  ]
}
JSON
FieldValue
changes[].opupsert (path, content, mode), delete (path), rename (from, to)
mode100644, 100755 or 120000
whenRFC 3339 with an explicit offset or Z
authorOptional; defaults to committer
expected_head_oidOptional; omitted means the branch is force-updated
allow_emptyOptional; defaults to false

A 201 answer names what moved.

ref
The full ref name, such as refs/heads/main.
oid, commit_oid
The new commit.
seq
The WAL sequence that published it.

Repository and tasks

Long work runs as a task. Send Accept: text/event-stream to follow it live.

RoutePurpose
PUT /{owner}/{repo}Create a repository
DELETE /{owner}/{repo}Delete a repository
GET /api/overviewRepository operational status
GET /api/opsList repository operations
POST /api/ops/{op}Run an operation as a task; needs write
GET /api/tasksList repository tasks
GET /api/tasks/{id}Get or attach to a task