Push and submit
push and submit publish a stack. They sit at the top level beside status
and restack, although they reach a remote, because publishing a stack is part
of managing it. push touches only Git; submit also opens pull requests, and
so invokes gh.
Both take a linear selection. A GitHub native stack is linear, so --scope
accepts only stack or path, and a selection that forks is refused with the
remedy rather than g2g choosing a line for you. Selecting a leaf is that remedy
and needs no flag: a leaf has no descendants, so stack collapses to an
ordered path by itself. See Scope.
How a branch maps to a pull request
Section titled “How a branch maps to a pull request”A branch is identified by its single open pull request. Closed and merged pull
requests left on a reused branch name are treated as history: they never block
github link, github retarget, or github status, and submit creates a
replacement rather than skipping the branch. Two or more open pull requests for
one branch is the only ambiguity, and it fails closed: a person has to close
all but one.
Commands
Section titled “Commands”g2g push --branch feature/top # preview; full-stack expansion is the defaultg2g push --branch feature/top --apply # every selected ref advances, or none dog2g push --remote upstream --apply # another name from git remote, not a branchg2g push is deliberately narrow: it publishes the selected linear path in one
git push --atomic with a --force-with-lease per branch, and never invokes
GitHub, submits, or restacks. Every selected non-trunk branch is pushed
bottom-to-top. The path may come from g2g’s own graph or from Graphite, and
--from g2g or --from graphite pins which (see
Sources). --remote defaults to origin and must
name a configured remote.
The preview shows the path, what each branch would publish, and the exact command:
Target synthetic-top
○ synthetic-main trunk │ ● synthetic-lower 2 commits to publish ● synthetic-top new branch on the remote ← target
Command to rungit push --atomic --force-with-lease origin synthetic-lower synthetic-top
Atomic push: all selected refs advance together or none do.Each lease is pinned to the remote tip the preview observed. A bare
--force-with-lease takes its baseline from the remote-tracking ref, and any
fetch between the preview and the push would disarm it.
A branch replayed since it was published, which is the ordinary state after a
restack, is shown as rewritten and pushed: the remote’s version is compared by
content, so a commit that is here under a new id is not mistaken for somebody
else’s. A commit the remote has that this checkout does not, by content, is
refused rather than dropped. The way out is to fetch and reconcile first, or to
run git push --force-with-lease <remote> <branch> yourself if you mean to
replace what is published.
A remote that does not support atomic pushes, or a rejected lease, fails the push. There is no non-atomic or unsafe-force fallback.
push asks the remote itself, because a lease has to be pinned to what is
there now. g2g status makes the same comparison from what the remote last
held here, without a network, so the two agree up to whatever has happened on
the remote since the last fetch.
push never calls gh, so it never touches pull requests, their bases, or the
stack comments.
submit
Section titled “submit”g2g submit is a preview-first publication path for a resolved linear stack.
With --apply it:
- validates the complete spec,
- revalidates immediately before mutating,
- performs one atomic, lease-protected push, as
pushdoes, - creates only the missing pull requests, bottom-to-top, as drafts,
- preserves existing pull requests, and
- keeps the stack comment on each pull request.
It never invokes gt submit, restacks Graphite, or retargets an existing pull
request. Moving a base that a restack left stale is
g2g github retarget, which has its
own preview.
g2g submit # previewg2g submit --edit --apply # write titles and bodies in $EDITOR, then publishThe submission spec
Section titled “The submission spec”Generate a reusable spec outside the repository, fill in each title, validate it, then apply it:
spec_dir="$(mktemp -d)"g2g submit --write-spec "$spec_dir"g2g submit --spec "$spec_dir/submission.json"g2g submit --spec "$spec_dir/submission.json" --applyThe spec is one JSON document with ordered branch, title, body and reviewer entries. Complex Markdown bodies are preserved exactly. If apply fails, the spec remains in place and the error gives the exact repair, validation, and retry commands.
g2g submit --edit creates one temporary submission.json document and opens
$EDITOR; it never opens a buffer per pull request. Add --apply to continue
after editing. The temporary spec is deleted only after a successful
--edit --apply, and --keep-spec retains it even then. Validation, editor,
interruption, and GitHub failures always retain it.
Drafts and ready for review
Section titled “Drafts and ready for review”Missing pull requests are opened as drafts. There is no --draft flag, because
a draft is the default and can be marked ready at any time. --ready is how you
ask for the thing that cannot be undone, since opening a pull request ready for
review notifies reviewers immediately.
--write-spec records the choice in the document, so an --apply that reads
it back does not silently drop it, and --no-ready overrules a spec that asks
for ready. The preview names what it is about to open and echoes --ready into
the command it suggests, so what you read is what runs.
Pull request templates
Section titled “Pull request templates”Repository pull request templates are detected from GitHub’s conventional
locations. One template pre-fills generated bodies. Multiple templates require
an explicit --template <name> or --no-template; g2g never guesses. Explicit
bodies in the spec win over templates.
Stack comments
Section titled “Stack comments”Once the pull requests are opened, submit keeps the stack comment on each of
them as its last act, because it has changed which pull requests the stack is
made of. The preview says so, and --no-comment skips it. If keeping the
comments fails, the pull requests that were opened stay opened, and the command
exits 3 and names g2g github comment --apply. See
github comment for what the comment
says and how it is kept.
Linking a native stack
Section titled “Linking a native stack”--link also links the complete stack as a GitHub native stack. That is
opt-in, because GitHub will not merge a linked pull request through
gh pr merge, which is how land merges each one. land refuses a linked
stack and names the g2g github unlink
that clears it.
Timeouts
Section titled “Timeouts”An interrupted submit can leave refs pushed and some pull requests created.
A mutation that runs out of time says so and states what may already have
happened; re-running with the same spec creates only what is missing. For a
slow network or a deep stack, raise the ceiling with the root --timeout
flag:
g2g --timeout 3m submit --spec "$spec_dir/submission.json" --applySee Timeouts.
After publishing
Section titled “After publishing”g2g github retarget --apply # fix bases a restack left staleg2g github status # check each pull request against the stackGitHub covers both, and Land takes a finished stack down onto its trunk.