Skip to content

Patterns

The Build a code hosting platform guide gets Git working: clone, push, and pages to read the result on. These patterns build on it. None of them is needed to serve Git.

Each page is written against the app the guide produces, and changes a part of it. Read the one you want; they do not need to be read in order.

PatternWhat it isCarried by
Repository lifecycleCreate, rename, and delete a repository, or make one by pushing to itRepositoryService, authorize
Protected branchesRefuse a force-push or a delete on a branchpre_receive
Merge requestsOpen one, show the change, merge itpost_receive, FindMergeBases, DiffCommit, IsAncestor, UpdateRefs
Merge queueLand on evidence, with no lock and no workerIsAncestor, UpdateRefs
ChecksEvidence instead of CI: whoever ran it reports the verdictYour own tables
Private repositoriesWho may read, and which refs they are told aboutauthorize, visible_refs
Deploy keysA credential scoped to one repository, and bot actorsauthorize
CI on pushBuild what landed, and read what changedpost_receive, DiffCommit, ListRefs
MirroringSync refs to another host as they landpost_receive, ListRefs, PushToRemote

Browsing a repository and rendering diffs are not here. They are chapter 6 and chapter 7 of the guide.

What every pattern assumes

These hold everywhere and are stated once, where they belong:

AssumptionStated in
The key is yours, and the create is idempotent on itRepository keys
actor is an ID in your namespace, never a credentialauthorize
An absent object ID is an unset field, never forty zerosObjectId
A refusal is per ref, and an unjudged command fails the pushpre_receive
Enroute holds no policy of its ownHooks

Two rules are about design rather than the contract, and every page here depends on them:

A rule lives outside what it gates. A policy a pusher can change by pushing is not a policy. What a merge is gated on belongs in your app's own configuration, reviewed and deployed like the rest of it, never in a file in the branch under test.

UpdateRefs does not run pre_receive. Use it for application-controlled merges instead of introducing a privileged Git identity solely to bypass a push rule.

Examples

The code is TypeScript on Next.js, continuing the guide's app: lib/store.ts for your own data, lib/enroute.ts for the client, and lib/hooks/ for the four calls. The contract is language-neutral, and so are these patterns — translate them into whatever you are building in.

Generated from docs/patterns/README.md at ead0474