Compatibility and storage
Recording and maintaining a stack’s structure needs only Git. Graphite and GitHub are integrations: g2g talks to them only when a command reaches for them, and the versions below matter only then.
Graphite
Section titled “Graphite”When Graphite is selected as a source, g2g uses Graphite CLI 1.8.6 as its tested compact-display baseline. Compatible patch and minor versions continue with a warning on stderr, while an unsupported major version or a changed display grammar fails safely.
g2g reaches Graphite only through its supported, non-interactive CLI. It never
reads Graphite’s private metadata database or configuration. Discovery is
read-only; g2g graphite mirror is
the one command that writes Graphite, through gt track and gt untrack,
gated on the same version check.
g2g will not run Graphite in a repository that does not already use it, because Graphite’s discovery creates state, and being asked whether Graphite applies must not be what enrols you. In such a repository g2g stays local. See Sources.
The contract g2g holds Graphite to is pinned in design-docs/graphite-cli-contract.md.
GitHub
Section titled “GitHub”GitHub projection requires a compatible gh with the relevant stack command:
gh stack link for github link and
gh stack unstack for github unlink.
Every command that reads or writes a pull request invokes gh; apart from
submit and land, those commands live under g2g github. push never
invokes it.
Where the graph lives
Section titled “Where the graph lives”The branch forest g2g records is stored at:
$(git rev-parse --path-format=absolute --git-common-dir)/g2g/graph.json--path-format=absolute matters: the bare --git-common-dir is relative to
the current directory, so it returns .git from the repository root and
../../.git from a subdirectory.
Because it lives in the Git common directory:
- Linked worktrees share it.
- It never appears in a diff or dirties a checkout.
- It is neither pushed nor shared between clones. A fresh clone starts empty, which matches the unpublished branches those edges describe: they do not survive a clone either.
To pick up a stack someone else published in a fresh clone, adopt it from its pull requests; see Adopting a published stack.
How it is written
Section titled “How it is written”Writes are a temporary file in the same directory plus a rename, so a
concurrent reader sees either the old graph or the new one, never a partial
write. Nothing is written without an explicit --apply.
The store records each branch’s parent and its fork point, the parent’s tip
when the edge was written. The fork point is what tells restack which commits
are the branch’s own, and it cannot be worked out after the fact once a merged
parent’s branch has been deleted. A branch’s own tip is deliberately not
stored, so an ordinary commit never looks like a change to the graph.
The graph carries its own storeSchemaVersion, separate from the --json
output’s schemaVersion (see Output).
They evolve separately. An unrecognised store version fails closed rather than
being rewritten.
See design-docs/g2g-owned-graphs.md for the model, the storage decisions, and what is deliberately left out.