Skip to content
GitmoapdocsBeta
Concept· Why does it work like that?Draft

Caching

Overview

Every response tells you how long you may keep it, in its Cache-Control header. Content addressed by a commit never changes, so it can be kept for a year without asking again; content addressed by a branch or tag is checked each time with an ETag, which costs only a header exchange when nothing moved; everything else is never stored.

The rule underneath is that git content is addressed by its content. The bytes of a file, a tree or a diff at a given commit are the same forever; the only thing that moves is which commit a branch name points at.

How it works

Four kinds of response

The API reference marks each operation with one of four kinds:

KindAddressed byCache-ControlExamples
immutable_shaa commit, a pair of commits, a package version, a stored fileimmutable, max-age=31536000a commit, a commit's diff, a diff page or file between two commits, a package download, a wiki page at a revision
ref_addresseda branch, a tag or HEADno-cache, with an ETagfile contents, a directory listing, commit history, a release archive, a spec document's content
derived_sha_artifactsomething that resolves to a pair of commitsmax-age=60a merge request's diff, a comparison of two branches, a stacked diff, a merge request's conflicts
uncacheableanything elseno-storelistings of work items, merge requests or members, every write, every response that carries a credential

no-cache does not forbid storing: it means keep the response, but check with the server before using it again.

Private or public

Each directive is preceded by private or public. A response is public only when the request carried no credentials and the resource is public — the only way a request without credentials can succeed. Any request made with a token or a signed-in session is answered private, so your own browser or build runner may keep the copy and no shared cache along the way may.

Checking again with an ETag

Most cacheable responses carry an ETag. Send it back as If-None-Match and, if nothing changed, the answer is 304 Not Modified with no body, repeating the Cache-Control so your stored copy stays fresh. On a branch-addressed read the ETag changes when the commit the branch points at changes, so polling an unchanged branch costs a header exchange.

A ref that is already a commit

When the ref you send is a full 40-character commit SHA, a branch-addressed read is answered as immutable, because nothing about it can change. An abbreviated SHA is not treated that way: it names one commit today and could name another later.

A branch-addressed read can also answer 302 Found, pointing at the same read at the commit the branch resolved to. Follow it, or send redirect=false to receive that address and the commit as JSON — url and sha — instead. Either way, the bytes then come from an address that never changes.

Derived diffs

A merge request's diff, or a comparison of two branches, is asked for by a name whose meaning moves when someone pushes. Its answer is good for a minute, and its body names the two commits it resolved to as base_sha and head_sha. Read the rest of that diff — further pages, every file's summary, one file, a range of lines — from the reads addressed by that pair, which are immutable.

Never stored

no-store covers every write, and every read whose answer is not tied to a commit — a listing of work items, a merge request, your profile. It also covers a redirect that carries a signed download address, even when what it points at never changes, because the address itself works as a credential until it expires.

  • Diffsthe pair-addressed diff reads and how a changeset is paged
  • Repositoriesreading files, directories and history at a branch or a commit
  • Egressthe byte budgets a cache helps you stay inside
  • Live streamswatching for change instead of polling