Graphite
Graphite is an optional source for g2g, never a requirement. Where a
repository already uses it, g2g can read the stacks it describes, adopt them
into its own graph, and mirror its own structure back. These commands live
under g2g graphite so that someone who does not use Graphite never has to
read about them.
Once g2g adopts a branch it stops asking Graphite about it, so without these
commands gt log would keep showing a structure that is quietly wrong.
g2g graphite mirror # what would it take for Graphite to agree?g2g graphite mirror --applyg2g graphite mirror --prune --apply # also untrack, in Graphite, what g2g does not record
g2g graphite adopt # adopt what Graphite declares into g2g's graphg2g graphite adopt --applyNeither command ever removes a branch from g2g’s graph. They keep the two records in step; they do not hand ownership over. A branch can sit in g2g’s graph, be tracked by Graphite, and appear in a GitHub stack all at once. See Sources for which record answers for a branch.
Both refuse outright in a repository that does not already use Graphite. Reading Graphite’s forest is what enrols a repository, so even a preview has to stop first. No g2g command enrols a repository, including the one that writes Graphite.
The two directions are not inverses
Section titled “The two directions are not inverses”Adopting and mirroring are not a symmetric pair, and adopting then mirroring
does not return you to where you started. A record in g2g’s graph carries a
fork point, the parent’s tip when the edge was written, which is what lets
restack work out which commits are a branch’s own. Graphite has nowhere to
put it. So adopting manufactures a fork point for each branch, and mirroring
has to throw it away.
graphite adopt |
graphite mirror |
|
|---|---|---|
| Writes | g2g’s graph only | Graphite only |
| Re-running | additive; never undoes | brings Graphite to the same answer again |
| On disagreement | refuses | overwrites Graphite; that is the job |
| Who answers for the branch afterwards | g2g | unchanged |
Commands
Section titled “Commands”graphite adopt
Section titled “graphite adopt”graphite adopt records what Graphite declares, so g2g can answer for those
branches and restack them. It writes only g2g’s graph, and it is additive: it
adds the edges g2g lacks, and refuses a branch g2g already records under a
different parent rather than silently reverting a deliberate change. That makes
it safe to re-run when someone tracks a new branch in gt.
It is not guessing. Graphite declares each parent, so the rule that track
never chooses a parent is not being relaxed; the declaration is the answer.
Branches Graphite names that this checkout lacks are skipped, since recording
one would put a branch in the graph that no command could act on.
Adoption is the authority claim. Afterwards g2g answers for everything it
adopted, and --from graphite is how you see Graphite’s view of those branches
again:
g2g status --from graphite # Graphite's record, drawn in g2g's formatg2g github status --from graphite # and its pull requests, as Graphite groups themGraphite is read whole, so graphite adopt takes neither --branch nor
--scope. A branch g2g records as a declared trunk is treated as a
disagreement rather than recorded under the parent Graphite shows for it (see
Shape the stack for declared trunks).
To adopt a stack from its pull requests instead, see Adopting a published stack.
graphite mirror
Section titled “graphite mirror”graphite mirror reconciles Graphite so it records what g2g’s graph records,
about the branches g2g knows, and leaves everything else in Graphite alone. It
writes only Graphite, and it is the only command that does. g2g keeps answering
for every branch it already answered for.
| g2g’s graph and Graphite | What the mirror does |
|---|---|
| g2g has an edge Graphite lacks | gt track --parent <p> |
| the two disagree about a parent | gt track --parent <p>, reparenting it |
| Graphite has an edge g2g lacks | nothing, unless --prune |
It works on the whole forest, branch by branch, and needs no pull request, push
or network. It names each branch explicitly to gt, so it never checks
anything out. Graphite requires a --parent it already tracks, so writes go
parents before children, and a g2g root Graphite has never heard of blocks the
mirror rather than being invented: only gt init establishes a Graphite trunk,
and enrolling a repository is not this command’s business.
--prune also untracks, in Graphite, the branches g2g’s graph does not record.
It is opt-in, because “this branch’s work has landed” is certain and “Graphite
knows a branch we do not” is not: it is just as likely to be one you tracked in
gt on purpose. A prune also refuses a branch whose child g2g does know,
because gt untrack takes the whole subtree with it, and the rest are pruned
deepest first. --prune is the only way the mirror removes anything from
Graphite, and g2g’s graph is never changed.
See design-docs/source-alignment.md for the reasoning behind both directions, and Compatibility and storage for the Graphite versions g2g supports.