Preview and apply
Preview first
Section titled “Preview first”All mutating commands preview first and require --apply. Run a command bare
and it describes what it would do, then ends by saying nothing changed:
Target auth · current Git branch
● auth ← target ● login needs restack ● session
Replays login and session onto auth.Applies without touching your working tree or checked-out branch.
No changes were made. Rerun with --apply to replay these commits.Nothing is written to g2g’s record without an explicit --apply either.
Observing a pull request base or inferring an ancestry edge produces a
preview, never a record.
Apply revalidates
Section titled “Apply revalidates”With --apply a command does not trust the preview you read. It re-discovers
the state and revalidates it against the preview before mutating, renders and
flushes the final plan first, and refuses ambiguous or unsafe work instead of
guessing. On success it prints a concise confirmation:
Ready to applyTarget auth · current Git branch
● auth ← target ● login needs restack ● session
Replays login and session onto auth.Applies without touching your working tree or checked-out branch.Replayed.Branch contents now match the recorded structure.
Suggested next step: g2g pushOn failure it never claims that changes were made.
Where a preview includes a command for you to run by hand, such as the
gh stack link command github link shows, copying it is a separate,
deliberate snapshot. Running it yourself does not make g2g re-resolve anything.
The one exception: moving the checkout
Section titled “The one exception: moving the checkout”up, down, top and bottom act without --apply, deliberately. Moving
the checkout changes no ref, record or remote, and git switch already refuses
to overwrite a local change, so a preview would only be a second command to
type. --dry-run says where they would go, and the git switch that gets
there, without moving. See Move around.
While a restack is unfinished
Section titled “While a restack is unfinished”restack is g2g’s only resumable operation. When it stops on a conflict, you
resolve it and run g2g restack --continue, or g2g restack --abort to put
everything back. Until then, every other command that changes anything
refuses: mid-restack a branch may already have moved while the record still
says where it used to be. See Restack, pull, prune.
What is deliberately not here
Section titled “What is deliberately not here”Interactive confirmation, or a cancellation or cooldown period before a
mutation, is intentionally deferred. It needs a separate safety design and is
not implied by the current --apply flow.
Exit status
Section titled “Exit status”| Status | Meaning |
|---|---|
0 |
it did what was asked, or there was nothing to do |
1 |
doctor only: it found something that needs putting right |
2 |
it failed, and achieved nothing |
3 |
it did part of what was asked and stopped somewhere you have to act |
Stopped part-way
Section titled “Stopped part-way”A command exits 3 when it did some of its work and then stopped:
pullstopping on a conflict mid-replay;pull --prunewhose prune refused after the pull had happened;landstopping part-way down a stack after something merged;github commentstopping after writing some of its comments;create -mwhose commit failed after the branch was recorded;- a
delete,foldorrenamethat could not put back what it had done.
A descent that stopped before changing anything is an ordinary failure.
These are not failures to retry, because what replayed stays replayed and what
merged stays merged. They are not successes either. Both print what happened
and what to do next; the status lets something reading only the status tell the
difference, the way git rebase and git merge exit non-zero when they stop
needing you.
Why doctor has its own status
Section titled “Why doctor has its own status”doctor’s 1 follows diff and grep: a script asking whether anything is
wrong wants the answer as a status, and 2 stays “could not tell”. See
Status and doctor.