refs/branch-metadata/).
The graph is available when those refs and the relevant branches have been
published and fetched:
- In a local clone,
rbs stack submitpublishes stack metadata, andrbs stack get <branch>retrieves a branch and its ancestors. An ordinary Git clone does not necessarily fetch these additional refs. - A fresh managed branch node restores available ancestry during initialization. This does not imply that it knows every descendant or every other stack.
- The editor, CLI and control plane use the same parent relationships, but a node’s fetched view can lag later remote changes. Missing or stale metadata must be resolved explicitly; it does not establish that a parent was merged.
Choose your workspace
The command examples below apply to a local clone, where you control the Git checkout. In the ReasonOS editor, each active branch has its own shared node. Switching branches connects your editor to another node; it must not change the checkout underneath teammates who are still using the original node.Managed branch workflow
- Save your editor changes and stage the files you want to carry into a new branch. Unsaved editor text is not part of the staged snapshot.
-
Use New stacked branch in the stack menu to review the staged changes and
commit message, then explicitly publish the branch. This creates a branch from
your staged work that teammates can build on.
rbs stack create <name> -m "Describe the change" --publish— creates and publishes the branch (-msupplies the commit message); expect confirmation and an Open workspace offer. - Choose Open workspace to connect to the new branch workspace. Creating the branch preserves the source branch’s checkout and staged changes; teammates remain connected to their current branch.
-
On the new branch, inspect the stack, preview submission, then submit it for review.
rbs stack log— shows the node’s known stack relationships; expect the new branch and its ancestors.rbs stack submit --dry-run— previews submission (--dry-runmakes no publication changes); expect a plan naming the selected branches and their review targets.rbs stack submit— pushes the selected branches and creates or updates their ReasonOS change requests; expect one result per branch, each request targeting its parent. Repository and change-request permissions are required.
create, --publish publishes the new branch. For submit, --publish
changes existing draft change requests to published requests; ordinary
submit already pushes the selected branches.
Creating an empty stacked branch from the UI
Choosing New stacked branch without Carry staged changes asks the control plane to create the branch for you: it is cut at the current branch’s tip and its stack metadata (the samerefs/branch-metadata/<branch> record the
CLI writes) is published together with the branch head in one step, so the
branch never exists without its parent relationship. Refs that already existed
before the attempt stay as they were. On success the editor opens the new
workspace. Three exceptional outcomes may need attention:
- Taken name — “A branch with this name, or its stack metadata, already exists on the origin. Refresh the branch list and pick another name.” Nothing was created.
- Unconfirmed — “ReasonOS couldn’t confirm whether the origin accepted the new branch. Nothing was undone — refresh the branch list before trying again.” If the branch appears after a refresh, it exists. If it does not, that is not proof the publication failed: confirm the branch is absent on the origin itself, or wait for a repository sync to complete successfully and refresh once more, before creating again. A second attempt against a branch that did land is refused as already existing, never duplicated.
- Recorded later — “The branch and its stack metadata are on the origin, but ReasonOS could not record it yet. It will appear after the next repository sync; stay on this branch and refresh the branch list before opening it.” You stay on the current branch; the notice belongs to that workspace and clears when you switch or close the menu.
Navigate to a parent from the terminal
On a managed node with the parent-navigation update, these commands offer a workspace to open:rbs stack down— selects the immediate parent; expect an Open workspace offer without switching the current workspace.rbs stack down 2— selects the ancestor two levels down, stopping at trunk; expect an offer naming that branch.rbs stack bottom— selects the first stacked branch above trunk; expect an offer naming that branch.
bottom on the first stacked branch
offers that same branch; navigation from trunk reports that it is already trunk.
Use a positive integer for the down count. For compatibility with the local CLI,
an invalid or nonpositive count currently defaults to one. Missing, malformed or cyclic
parent metadata refuses navigation. Managed up and top remain unsupported:
a fresh node may know its ancestors without having the full descendant graph.
Recovering from a managed operation error
If an error reports a retained temporary commit workspace, inspect the reported path and resolve the lock or access problem before removing it through Git’s worktree tools. Do not delete the directory blindly. A cleanup failure stops publication and preserves that workspace for recovery. A missing parent branch does not prove its changes were merged. An unresolved parent must be repaired or reviewed before submission; do not recreate or retarget it simply to dismiss the error.Set up a local clone
rbs stack init— configures stacking in this local clone; expect the chosen trunk and remote, plus project guidance if no review destination is configured.
rbs stack submit can open change requests:
rbs stack init main --remote origin --control-plane https://hub.example.com --project my-service— sets trunk, remote and review destination; expect confirmation namingmain,originandmy-service.
The local-clone daily loop
rbs stack create add-api -m "Add the API"— commits staged work on a new local branch (-msupplies the message); expectCreated add-api on <parent>.rbs stack create add-ui -m "Add the UI"— creates the next local branch on top; expectCreated add-ui on add-api.rbs stack log— shows the stack; expect the parent-child chain including both branches.rbs stack modify -a— stages saved changes, amends the current branch and restacks descendants; expect updated commits or a conflict that needs resolution.rbs stack sync— updates trunk and dependent branches; expect sync/restack progress or an actionable conflict.rbs stack submit --stack— submits the current branch, its ancestors and its descendants (--stack); expect parent-targeted change-request results, or a permissions/configuration diagnostic.
When local creation says nothing is staged
Saving a file does not stage it for a commit. In a local clone, inspect the changes and stage the files you intend to include before creating the branch:git status --short— lists pending changes; expect changed paths, with??marking untracked files.git add path/to/file— stages the selected file; expect no output on success.rbs stack create add-api -m "Add the API"— creates a local branch from the staged changes; expect creation confirmation, or a diagnostic if there is nothing to commit.
?? is untracked, not a clean working tree. Updated RBS
builds name untracked files in the refusal. A failed Git status check is reported
as an error rather than being described as a clean tree. Resolve that error
before retrying.
Use selected paths when staging. rbs stack create <branch> -a stages every change in the
working tree, which can include another person’s edits in a shared checkout.
Use --empty only when you deliberately want a branch before making the change.
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
git checkout main— switches this local clone to trunk; expectmainto be checked out. Do not use this to switch a shared branch node.rbs stack create add-hpc-module -a -m "Add the HPC module"— creates the module branch using all saved changes (-a); expect confirmation namingmainas parent.rbs stack create add-hpc-dashboard -a -m "Add the HPC dashboard"— creates the dashboard branch after you add its code; expectadd-hpc-moduleas parent.rbs stack create add-ssh-client -a -m "Add the SSH client"— creates the client branch after you add its code; expectadd-hpc-dashboardas parent.
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 submit --stack— publishes the current branch, its ancestors and its descendants for review; expect one request per non-trunk branch, each targeting its parent.
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:
git add -p— stages changes interactively (-pselects individual hunks); expect prompts asking which changes to stage.rbs stack absorb --dry-run— previews where staged hunks belong; expect proposed destinations without changing commits.rbs stack absorb— applies the staged hunks to their owning branches; expect updated commits and restack results, or a diagnostic when ownership cannot be resolved.
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:rbs stack modify --into add-hpc-module— directs the amendment into the named branch (--into); expect that branch and affected descendants to update, or a conflict to resolve.
4
Land from the bottom, then sync
The module’s change request merges. Now:
rbs stack sync— incorporates remote trunk changes and restacks remaining work; expect progress showing affected branches or conflict guidance.
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
rbs stack modify -a— stages saved changes and amends the current commit; expect descendants to restack or stop at a conflict.rbs stack modify -c -m "wip"— creates an additional commit (-c) instead of amending; expect a newwipcommit and any required restack results.
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:
rbs stack continue --all— stages the resolved files (--all) and resumes the interrupted operation; expect continuation or the next conflict.rbs stack abort— cancels the interrupted restack; expectRestack aborted.after recovery succeeds.
Mistakes: undo
rbs stack undo --dry-run— previews the recorded state to restore; expect a restoration plan without changing it.rbs stack undo— restores the recorded branches and metadata; expect undo results, or a diagnostic if no suitable undo record exists.
undo never deletes commits — branches created since are kept, just untracked.
Running undo again redoes.
Testing every branch: test
rbs stack test 'rbs build //...'— switches this local clone through the selected branches and builds each; expect per-branchokorFAILresults.rbs stack test --downstack --fail-fast 'rbs build //... && rbs query //...'— selects the current branch and its ancestors (--downstack) and stops on the first failure (--fail-fast); expect per-branch results and any remaining branches markedskipped.
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,
rbs stack submit --stack --draft— submits the current branch, its ancestors and its descendants with new requests marked as drafts; expect draft-request results.rbs stack submit --publish— takes existing review drafts out of draft status; expect publication/update results. This flag has a different purpose fromcreate --publish.rbs stack submit --update-only— updates existing requests without opening new ones; expect updates, up-to-date results or skips for branches without requests.rbs stack submit --dry-run— previews submission; expect a plan without pushes or new requests.
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.