Land a change¶
Landing is the everyday "ship it" verb. tovio land my-lane --into main integrates a
lane's work onto a target lane and then automatically rebases
every change stacked on top of it so your stack stays intact. Change IDs are preserved throughout —
the work keeps its identity.
Landing is one undo away
tovio land, including its whole rebase cascade, is reversible as a single tovio undo. If a land
isn't what you wanted, take it back in one command — the lane and every descendant return to where
they were. See Undo and redo recorded operations for the local retention and peer-observation boundaries.
What's shipped, and what's still ahead
tovio land and the change/stack model are in the core today: landing with --into, the
automatic (path-scoped) rebase cascade across a stack, op-logged and undoable lands, --dry-run
and --explain previews, an opt-in linear --rebase land, and landing several lanes at once —
all with Change IDs preserved throughout. Two parts on this page are still ahead: --async
background landing (not in the shipped grammar), and the team-tier pre-land gates (proposal
approval, required-check enforcement, policy clearance) that belong to lane protection and the
Forge. Both are called out where they appear below.
flowchart LR
L["tovio land my-lane<br/>--into main"] --> G{"land gates<br/>(conflict-free, policy,<br/>required plugins)"}
G -- pass --> M["main advances"] --> C[["Automatic rebase cascade<br/>chg:002, chg:003 re-parented<br/>Change IDs preserved"]]
G -- block --> X[["✗ Blocked with reason<br/>+ next steps"]]
More diagrams for the full day-to-day loop: Branching, committing & merging workflows.
Land a change onto a lane¶
✓ landed `my-lane` into `main` blake3:e9176f9d24…
2 file(s) merged · same Change IDs — your work kept its identity · undo with `tovio undo`
--into names the target lane (default main); with no positional lane the source is the lane
you're on. TOVIO advances the target to include your lane's work (and any not-yet-landed ancestors),
writing a merge commit when the two have diverged, then re-parents the descendants. When main hasn't
moved since you branched, the land is a plain fast-forward:
✓ fast-forwarded main → my-lane blake3:e36deb9075…
same Change IDs — your work kept its identity · undo with `tovio undo`
Preview before you land¶
tovio health says whether the current lane is clean, landable, and how stale it is. To see the whole
decision — merge base, per-file algebra, gates — without advancing any ref, trace it:
That is the merge lens of tovio explain; --explain without --dry-run prints the
trace and then lands for real.
The automatic rebase cascade¶
This is what makes stacked work painless. Say your lane my-lane sits on main, with two more changes
stacked above it on a dependent lane:
Landing my-lane carries the rest along — no manual rebase:
✓ landed `my-lane` into `main` blake3:e9176f9d24…
2 file(s) merged · same Change IDs — your work kept its identity · undo with `tovio undo`
Rebased 2 descendant change(s) on 1 lane(s): my-stack (Change IDs unchanged)
The line that matters: Change IDs unchanged. chg:002 and chg:003 are the same changes they were
before — same stable names, new commit hashes. Anyone (you, a teammate, CI) can still point at
"chg:002" and mean the same unit of work.
The cascade is path-scoped: a descendant lane whose files don't overlap what the integration changed
is deliberately left alone and reported as such (N lane(s) left alone (no overlapping paths)), and a
protected descendant lane is never rewritten — it is reported as NOT rebased with a
tovio change rebase … --onto hint so you can re-stack it deliberately.
Conflicts never block the cascade¶
If a descendant can't rebase cleanly, TOVIO stores a conflict object and keeps cascading to the remaining descendants. The land still completes; the conflicted change keeps existing on top of the conflict and you resolve it when ready. The same holds for the land itself when the target is not a protected lane:
✓ landed `my-lane` into `main` with 1 conflict(s) blake3:fd9764d8b6…
⚠ content src/integrations/cgm/dexcom.ts
nothing is blocked — the conflicts are stored as data.
resolve them: tovio resolve
list them: tovio status --conflicts
A conflict is data, not a failure — see Resolve conflicts.
Land linearly (--rebase)¶
By default a diverged land writes a merge commit, so each landed change survives verbatim as the
reviewed, attested commit it was. If you want a linear mainline instead, --rebase re-derives the
source lane's changes onto the target tip (Change IDs preserved) and fast-forwards:
✓ rebased `my-lane` onto `main` blake3:a0594721d8…
linear — same Change IDs, re-signed by you · undo with `tovio undo`
The cost is that each change is re-signed by you, the lander — which is why merge/fast-forward stays
the default. --rebase is two-way only.
Land several lanes at once¶
List two or more source lanes and land folds them over their common base into one multi-parent
commit — a native "octopus" land:
Land in the background (--async)¶
land is synchronous: it blocks until every descendant is re-parented, then prints one predictable
summary. The CLI specification also designs an --async form that defers the cascade to a background
operation and returns the terminal immediately, for rapid or agent-driven workflows.
Not yet available
--async is not in the shipped grammar; every land, including its cascade, runs synchronously
today.
Landing onto a protected lane¶
Protected lanes like main or release are guaranteed buildable, so landing onto one requires a
conflict-free change. If the change still has unresolved conflicts, the land is refused with
TVO-CONFLICT-003 — no ref advances and no conflict object is written — and the message tells you how
to proceed:
✗ Cannot land: 1 unresolved conflict(s)
Landing `my-lane` into protected `main` leaves 1 unresolved conflict(s):
content src/integrations/cgm/dexcom.ts
See where the branch stands:
tovio health
List the conflicts:
tovio status --conflicts
[TVO-CONFLICT-003] https://tovio.dev/errors/TVO-CONFLICT-003
That is the three-part shape every TOVIO error uses: what happened, why, then the runnable next
steps and the stable code. tovio resolve clears the conflicts; tovio change health <change-id>
re-checks landability once you have.
On a protected lane, land is designed to run every configured pre-land gate and report each one,
refusing only if a gate fails:
$ tovio land my-lane --into main
Pre-land checks:
✓ Proposal approved (alice)
✓ No unresolved conflicts
✓ Required checks passed (build + tests)
✓ No policy-protected files modified without clearance
✓ Landed: chg:a3f7b2 → main @ gh1234
This gate is re-enforced server-side too, so it can't be skipped by pushing directly.
Conflicts can live in flight — they just can't land
A change in progress may carry conflicts and you keep working normally. The protected-lane gate only stops conflicts from reaching shared, must-build code. Landing onto an unprotected lane may carry conflicts, like any in-flight change.
Some pre-land gates are team-tier
The conflict-free gate, the exclusive-lock gate, and the semantic-check gate run locally today
(tovio explain merge lists them under Gates). Proposal approval, required-check enforcement,
and policy clearance belong to lane protection (tovio policy protect) and the Forge; the Forge
and its pre-land gate are built and tested, but not yet run in production, and the checklist above
is the designed rendering. See Collaboration & files for the
proposal/review workflow.
Land vs. merge vs. rebase¶
land(everyday) — integrate a lane's changes onto a target lane and cascade the rebase to the stack. This is your primary "ship it" verb.merge— the CLI specification designs a standalonetovio mergefor combining two lanes; it is not implemented.land --intocarries the same stored-conflict semantics.rebase(advanced) — explicitly re-parent changes onto a new base.landis the everyday form of the same idea; see Rewrite history safely.
Where to go next¶
- A conflict blocked the land onto a protected lane? → Resolve conflicts
- Landed the wrong change? → Undo and redo recorded operations
- Need to reshape a change before landing? → Rewrite history safely
Last reviewed September 9, 2026
Suggest an improvement to this page Not for security reports — see disclosure