Forks & Templates
Instant forks for parallel agent swarms. Snapshot parent refs in milliseconds, share blobs through a global content-addressed store, no storage copy.
Overview
Coregit forks are instant. Default-mode POST /v1/repos/:slug/fork returns
in milliseconds regardless of parent size, by snapshotting the parent's refs
and materializing reference-count edges into a global content-addressed blob
store — never copying storage bytes. Spinning up 50 parallel agent branches off the
same parent is essentially free.
For platforms that need a fully self-contained copy (no chain to the parent),
pass mode: "deep" and the fork is created as a chain-flattened standalone.
Create a Template
Mark any repository as a template using is_template on create or update:
POST /v1/repos{
"slug": "nextjs-starter",
"is_template": true,
"visibility": "public",
"description": "Next.js starter template"
}Or update an existing repo:
PATCH /v1/repos/nextjs-starter{
"is_template": true
}List Templates
GET /v1/repos?is_template=trueFork a Repository
POST /v1/repos/:slug/fork
POST /v1/repos/:namespace/:slug/fork{
"slug": "agent-001",
"namespace": "alice",
"description": "Agent run from nextjs-starter",
"mode": "instant"
}| Field | Required | Description |
|---|---|---|
slug | yes | Target repo slug. |
namespace | no | Target namespace. |
description | no | Defaults to source description. |
default_branch | no | Defaults to source default branch. |
mode | no | "instant" (default) — point-in-time snapshot, no storage copy. "deep" — chain-flattened standalone. |
Response 201:
{
"id": "fork_xyz789",
"namespace": "alice",
"slug": "agent-001",
"description": "Agent run from nextjs-starter",
"default_branch": "main",
"visibility": "private",
"is_template": false,
"forked_from": {
"repo_id": "repo_abc123",
"org_id": "org_456",
"slug": "nextjs-starter",
"namespace": null
},
"fork_mode": "instant",
"fork_depth": 1,
"fork_root": "repo_abc123",
"blob_materialization": "sync",
"shared_blobs": 18432,
"owned_blobs": 0,
"git_url": "https://api.coregit.dev/myorg/alice/agent-001.git",
"api_url": "https://api.coregit.dev/v1/repos/alice/agent-001",
"created_at": "2026-04-29T02:30:44.445Z"
}| Response field | Meaning |
|---|---|
fork_mode | Effective mode used. May differ from request when fork_depth > 16 forces auto-flatten to "deep". |
fork_depth | Distance from the chain root. 1 for a direct fork of a non-fork. |
fork_root | Repo ID at the chain root. Equals the new repo's id when fork_mode is "deep". |
blob_materialization | "sync" — every reachable blob got a blob_repo edge inline. "queued" — large parent; remaining edges are written by a background queue, reads still work via the chain in the meantime. |
shared_blobs | Reachable blob count materialized at fork time. |
owned_blobs | Blobs the fork itself wrote. Always 0 immediately after creation. |
What Happens During an Instant Fork
- No storage copy. Git objects live in a single global content-addressed
keyspace (
_blobs/{sha[:2]}/{sha[2:]}) shared across every repo in your org. Forking just records that the new repo references those existing blobs. - Refs are snapshotted. Parent's branch + tag SHAs at fork time are
written to a
fork_snapshotrow. The fork'sGET /refsandGET /commitsread from the snapshot until the fork pushes. - First push is copy-on-write. Writing to a ref in the fork shadows the snapshot for that name; the parent is never touched.
- Blob refcount edges (
blob_repo) are materialized. Sync probe up to ~5000 reachable objects; larger parents queue the rest in the background.
Fork Behavior
- Forks are independent on writes. Pushes to the parent are not visible through the fork — the snapshot is the durable point-in-time anchor.
- Forks are private by default (
visibility: "private"). - Forks are never templates (
is_template: false). - Deleting the parent does not affect existing forks. Each fork holds its
own
blob_repoedges, so the parent's blobs survive in the global store for as long as any fork still references them. Garbage collection sweeps orphaned blobs after a 7-day grace period. - Cross-org forks of public templates support both modes; permission to fork is checked at fork-time and sealed into the fork's refcount edges.
Multi-Level Forks (chain depth)
Forks of forks are first-class. Each fork carries:
fork_root— the repo at the top of the chain.fork_depth— distance from the root (1,2, ...).- An internal
fork_chain— the ordered list of ancestors, capped at 16.
When fork_depth would exceed 16, the API auto-flattens the new repo to
mode: "deep" instead. This keeps read paths bounded to a single SHA lookup
in the global blob store.
Search on Forks
Semantic search and code-graph queries on an instant fork transparently fan out to the parent's namespaces and merge results. The fork's own results take priority on dedup. As the fork diverges and re-indexes, its own namespace takes over.
mode: "deep" (and pre-existing "copied" forks created before instant
forks landed) are self-contained — searches stay scoped to the fork's
namespace alone.
Access Control
| Scenario | Required |
|---|---|
| Same-org fork | Read access on source repo. |
| Cross-org fork | Source must be is_template: true AND visibility: "public". |
SDK
import { createCoregitClient } from "@coregit/sdk";
const cg = createCoregitClient({ apiKey: process.env.COREGIT_API_KEY! });
const { data, error } = await cg.repos.fork("nextjs-starter", {
slug: "agent-001",
// mode: "instant" is the default — omit to get instant forks.
});CLI
cgt repos fork nextjs-starter --slug agent-001
cgt repos fork nextjs-starter --slug agent-deep --mode deepThe default is instant. Pass --mode deep only when you need a
chain-flattened standalone copy.