refs/branch-metadata/),
not in a service or a local database. That has three consequences you’ll feel every
day:
- A clone carries its stacks. Push a stack and any teammate, CI runner, or branch node reconstructs the same graph — no account, no extra server round-trip.
- The whole stack survives you switching machines —
rbs stack getrebuilds it from the refs alone. - Your teammates and the control plane see the same graph you do, because
rbs stack submitpushes the metadata along with the branches.
Set up once per clone
rbs stack submit can open change requests:
The daily loop
A worked example
Say you’re adding an HPC dashboard, and the work naturally splits into a module, a dashboard that uses it, and an SSH client on top.1
Build the stack, one small branch at a time
create branches off the branch you’re standing on, so the three branches
form a chain over trunk. rbs stack log draws it; rbs stack ls lists it one
line per branch.2
Submit the whole stack for review
rbs stack diff shows you the same parent-relative diff a reviewer
sees.3
Respond to review feedback on a lower branch
A reviewer asks for a change in the HPC module — the bottom branch. Make the fix
anywhere in the stack, stage it, and let rbs place it:
absorb figures out which downstack branch introduced the lines each staged hunk
touches, amends that branch, and restacks everything above it. The feedback lands
in the change request being reviewed instead of as a “fix review comments” commit
on top of the stack. A hunk that could belong to more than one branch stays
staged, with the reason listed.Alternatively, if you know exactly where a fix belongs:4
Land from the bottom, then sync
The module’s change request merges. Now:
sync fast-forwards trunk from the remote, refreshes what each branch’s change
request says, deletes branches whose changes are already in trunk (reparenting
whatever was stacked on them), and restacks the rest. The dashboard branch now
sits directly on trunk; the SSH client sits on the dashboard. Repeat until the
stack is empty.A branch counts as landed when its content is in trunk — squash- and
rebase-merges included, which plain commit ancestry would miss.Keeping a stack healthy
Amending: modify
modify always restacks the branches above the one you amended. That is not
optional: leaving the branches above pointing at a commit that no longer exists is
how a stack rots.
Conflicts: continue and abort
A restack that hits a conflict stops and tells you. Resolve the files in your
editor — even hours later; the paused restack survives the process ending — then:
Mistakes: undo
undo never deletes commits — branches created since are kept, just untracked.
Running undo again redoes.
Testing every branch: test
Scope flags
Most stack-wide commands (submit, restack, test) take the same four scope
flags:
Full command surface
Two worth calling out:
rbs stack get <branch>fetches a branch and every branch below it, reconstructing the stack from the metadata the submitter pushed. If your local copy of a branch has truly diverged from the remote,getrefuses unless you pick--rebase(replay your commits on top) or--overwrite(discard your copy).rbs stack log --jsonemits the stack as a document, so scripts and agents can read the graph without scraping the drawing.
What submit does, precisely
For each branch in scope, bottom-up, rbs stack submit:
- pushes the branch (with a lease — a restacked branch has rewritten history by
definition, but rbs will not clobber remote work it hasn’t seen unless you pass
--force), - opens or updates a ReasonOS change request targeting the branch below it,
- records the request number in the branch’s metadata,
submitneeds a control plane to open change requests in. Configure one withrbs stack init --control-plane <url> --project <name>, or setRBS_CONTROL_PLANE_URLandRBS_PROJECT_NAME.- By default
submitapplies downstack — this branch and everything below it. Pass--stackto submit the whole stack from anywhere in it.
Stacks and branch nodes
ReasonOS runs one server per branch: each active branch gets its own branch node, and the editor connects to it. A stack is therefore a chain of workspaces, not just a chain of refs — and because the stack graph lives in git, every node in the chain (and the control plane, which reads the same refs from its mirror) sees the same picture without any extra coordination. Creating a stack withrbs stack create is also how you get a node
per reviewable unit of work: small branches mean small diffs and focused
workspaces.