TSTier SlateAll templates

Collaboration

Version control - the commit graph is a DAG

Why history is a graph rather than a list, and what that costs at merge, at fetch and at garbage collection.

  • System design
  • deep
  • 9 step walkthrough
  • 5 tables

Share

  • Facebook
  • X

What this board gets wrong on purpose

The tension

Content addressing buys free deduplication, cheap verification and an audit trail nobody can forge, and it pays for all of it with an object store that cannot forget. A force-push does not delete a commit, it moves a ref; the objects stay, reachable by hash, until a garbage collection that is deliberately conservative - it will not prune anything younger than two weeks, because pruning an object a concurrent push is halfway through referencing corrupts the repository. So a committed credential is live on the server for at least a fortnight after the mistake, is already in every clone taken since, and the only real remedy is to rotate the secret. The board also leaves the ref update as a bare compare-and-swap: it makes the last push win safely, and it gives the loser no merge and no queue, only a rejection and a human. And garbage collection is a full reachability walk of a graph with no incremental answer, so the housekeeping cost of a repository is a function of its whole history rather than of its recent activity.

Requirements

Ask these before drawing anything

  • Is history immutable, or may it be rewritten? "Immutable objects, mutable refs" answers both at once and is the decision the rest of the board depends on.
  • Must two people be able to work offline and merge later? If yes, history cannot be a numbered sequence, because nobody can allocate the next number.
  • How large may a single file be? Content addressing stores a whole new object for a one-byte change, so a 2 GB binary edited weekly is 100 GB a year of objects that delta-compress against nothing.
  • How large may the whole history be? Clone cost is a function of history, not of the working tree, and this is what makes a twenty-year-old repository painful rather than the number of files in it.
  • Do we need per-line attribution? That is a walk back through the graph per line, not a stored fact, and its cost is what makes blame slow on a busy file.
  • Is a monorepo in scope? Partial and shallow clones stop being optimisations and become requirements somewhere around 10 GB of history.
  • What happens when somebody commits a credential? Decide this before it happens, because the honest answer - rotate the secret - is unpopular enough that people go looking for a delete button instead.
  • Who may force-push, and to what? The compare-and-swap protects the repository from corruption; it does not protect a branch from a person.

Functional

  • Record a snapshot of a working tree as an immutable commit naming its parents.
  • Create, move and delete branches - which are names for one hash and nothing else.
  • Fetch from a remote by exchanging what each side has, transferring only the difference.
  • Merge two branches using their common ancestor, reporting conflicts rather than guessing.
  • Walk history: ancestry, reachability, and per-line attribution.
  • Recover a branch that was moved by mistake, for as long as the ref log retains it.

Non-functional

  • Object integrity: every object is verifiable against its own name. Corruption is detectable locally with no remote and no checksum file.
  • A push either fully lands or does not land at all. A partially published set of objects is a broken repository, not a slow one.
  • Ref updates are linearisable per ref. Two pushes racing on one branch: exactly one wins and the other is told clearly.
  • Clone of a 1 GB repository: under 4 minutes at 50 Mbps. Fetch of a day’s work: under 2 seconds.
  • 99.95% for fetch and clone. Push may be briefly refused under load; refusing a push is safe, accepting half of one is not.

Out of scope

  • Code review, which is a different board - the branch update here is its input.
  • Large-file storage as a separate service, which exists precisely because content addressing is the wrong shape for a 2 GB binary.
  • Signing and trust policy, which sits on top of the hashes rather than inside them.

The rest of this board

Board preview

Available on Tier Slate

This page publishes the question. The answer — 5 more written pages, a 9-step narrated walkthrough and a 5-table schema — is the board itself, and it opens in Tierslate.

  • 5written pages
  • 9walkthrough steps
  • 5tables37 columns

5 pages behind this one

  • Capacity estimation
  • Storage estimation
  • Availability
  • How it works
  • Deployment plan
Open this board in TierslateBrowse every board

More boards

Several people editing one thing without losing an edit.

  • Calendar scheduling - a time that suits five people
  • Code review - the comment is on a line that moved
  • Collaborative editor - two carets in one paragraph
  • Whiteboard sync - the cursors cost more than the drawing
All 50 templatesOpen Tierslate
Tierslate

tierslate.com

HomeTemplatesPrivacyTerms