g2ggot 2 go. your stack doesn't.

g2g records the stacked branches in your repository, then restacks, publishes and lands them. Every command previews first and acts only with --apply, so you can hand the stack to an agent and walk away.

  • Git alone to record and restack
  • GitHub to publish and land
  • Graphite optional, never required
brew install shhac/tap/g2g
Read the docs
#your-stack09:05back
  1. <you> fixed auth. restack everything on it and push when it reads clean

  2. <you> g2g

  3. * you are away

  4. <agent> $ g2g restack

    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.
  5. <agent> preview is clean. applying.

  6. <agent> $ g2g restack --apply

    Ready to apply
    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.
    Replayed.
    Branch contents now match the recorded structure.
    
    Suggested next step: g2g push
  7. <agent> $ g2g top

    Switched to session  · top of the stack from auth
  8. <agent> $ g2g push

    Target  session  · current Git branch
    
      ○ main     trunk
      │
      ● auth     new branch on the remote
      ● login    new branch on the remote
      ● session  new branch on the remote  ← target
    
    Command to run
    git push --atomic --force-with-lease origin auth login session
    
    Atomic push: all selected refs advance together or none do.
    
    No changes were made. Re-run with --apply to push.
  9. <agent> $ g2g push --apply

    Ready to apply
    Target  session  · current Git branch
    
      ○ main     trunk
      │
      ● auth     new branch on the remote
      ● login    new branch on the remote
      ● session  new branch on the remote  ← target
    
    Command to run
    git push --atomic --force-with-lease origin auth login session
    
    Atomic push: all selected refs advance together or none do.
    Applied — remote refs updated atomically
    Changes were made.
  10. <agent> $ g2g doctor

    Target  every recorded stack  · repository
    
    
    Nothing needs putting right across 3 recorded branches.
  11. * you are back

  12. <you> wat

  13. <agent> 2 branches restacked, 3 pushed, nothing needs putting right.

  14. <you> lgtm

Preview and apply afk

Every command that changes anything shows its plan first and acts only when you add --apply. Anything ambiguous is refused, together with the command that would put it right. That is what makes it safe to leave an agent running g2g while you are somewhere else.

Preview and apply in the docs →
g2g create login -m "Add login"

Target  login  · new branch

  ○ main   trunk
  │
  ● auth
  ● login  new  ← target

Commands this would run, in order
  1  git switch -c login auth  · start login at auth and check it out
  2  g2g track --branch login --parent auth --apply  · record it under auth
  3  git commit -m 'Add login'  · commit what is staged

Creates login at ab0c00ad2b9d, the tip of auth, and switches to it.
Records login under auth.
Commits 1 staged file (login) onto it.
Graph store · /work/app/.git/g2g/graph.json

No changes were made. Rerun with --apply to create it.

Restack brb

Change a branch in the middle of a stack and restack replays everything above it onto the new tip, without touching your working tree or checked-out branch. When the trunk moves, pull fetches it, fast-forwards it, replays the stack, and with --prune forgets what landed.

Restack in the docs →
g2g restack

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.

Submit ptal

push publishes the stack in one atomic push: every branch advances, or none do. submit opens the missing pull requests as drafts and keeps a map of the stack on each one, so reviewers can see where they are.

Submit in the docs →
g2g push

Target  session  · current Git branch

  ○ main     trunk
  │
  ● auth     new branch on the remote
  ● login    new branch on the remote
  ● session  new branch on the remote  ← target

Command to run
git push --atomic --force-with-lease origin auth login session

Atomic push: all selected refs advance together or none do.

No changes were made. Re-run with --apply to push.

Land lgtm

From the top of the stack, land merges it down onto the trunk, bottom first. It lists every step, and which ones are blocked and why, before it takes any of them.

Land in the docs →
g2g land

Target  synthetic-two  · current Git branch

  ○ synthetic-main   trunk
  ├─● synthetic-one  #41  base✓  merge
  └─● synthetic-two  #42  head✗ publish first  base✗ → synthetic-main  merge with --admin  ← target

Commands this would run, in order
   1  gh pr merge 41 --squash  · land synthetic-one
   2  g2g pull --apply  · advance the trunk and replay what is left onto it
   3  g2g prune --branch synthetic-one --scope branch --apply  · forget it, once what sat on it has been reparented
   4  git push origin --delete synthetic-one  · remove the published branch, if the merge has not already
   5  git branch -D synthetic-one  · remove it here
   6  g2g push --branch synthetic-two --scope path --apply  · publish it as it is here
   7  gh pr edit 42 --base synthetic-main  · merge into synthetic-main rather than synthetic-one
   8  gh pr merge 42 --squash --admin  · land synthetic-two
   9  g2g pull --apply  · advance the trunk and replay what is left onto it
  10  g2g prune --branch synthetic-two --scope branch --apply  · forget it, once what sat on it has been reparented
  11  git push origin --delete synthetic-two  · remove the published branch, if the merge has not already
  12  git branch -D synthetic-two  · remove it here

Install ttyl

Install with Homebrew, then record the stack you are on. The trunk is named once; after that, g2g knows it.

$ brew install shhac/tap/g2g
$ g2g adopt --trunk main --apply
$ g2g status

Handing the stack to an agent? Give it the g2g skill, so it reads every preview before it adds --apply.

$ npx skills add shhac/agent-skills --skill g2g --global