Skip to content

Branching, committing & merging — workflows & diagrams

Visual references for TOVIO's day-to-day loop: how lanes, changes, commits, merges, and lands actually fit together. Prose lives on The change model, Coming from Git, and the everyday guides (lanes, commit, land, rewrite history) — this page is the map.

How to read these

Rectangles are states or artifacts, rounded shapes are actions, and diamonds are decisions. Two ideas recur: you live in a change, not on a lane, and lanes are landing targets — lightweight mutable CRDT pointers, not workspaces.

1. Git model vs. TOVIO model (day-to-day loop)

The single biggest difference: no staging area, no "detached" states, no force-push, and a lane is a target — not where your uncommitted work lives.

flowchart LR
    subgraph GIT[" Git day "]
        G1["edit"] --> G2["git add"] --> G3["git commit"] --> G4["git push"] --> G5{"conflict on merge?"}
        G5 -- yes --> G6[["HALT: fix markers"]]
        G5 -- no --> G7([merged])
    end
    subgraph TOVIO[" TOVIO day "]
        V1["edit<br/>(auto-tracked in current change)"] --> V2["tovio commit -m"] --> V3["next change<br/>started automatically"] --> V4["tovio sync"] --> V5{"auto-merges?"}
        V5 -- yes --> V6([reconciled])
        V5 -- no --> V7[["✓ reconciled + conflict stored<br/>work continues"]]
        V6 --> V8["tovio land --into main"]
        V7 --> V8
    end
    classDef halt fill:#fdd,stroke:#c33,color:#600;
    classDef ok fill:#dfd,stroke:#3a3;
    class G6 halt;
    class V6,V7,V8 ok;

Prose: Coming from Git.

2. Lanes are landing targets, not workspaces

A lane is a CRDT mutable pointer to a change. You don't check one out to work; you work in a change and later land it onto a lane.

flowchart LR
    subgraph WORK[" Where work lives "]
        CHG1["chg:001<br/>(your current change)"]
        CHG2["chg:002<br/>(stacked on chg:001)"]
        CHG3["chg:003<br/>(stacked on chg:002)"]
        CHG1 --> CHG2 --> CHG3
    end
    subgraph TARGETS[" Landing targets "]
        MAIN(["lane: main<br/>→ points at some landed change"])
        REL(["lane: release-1.2<br/>→ points at another landed change"])
    end
    CHG3 -. "tovio land --into main" .-> MAIN
    CHG2 -. "tovio land --into release-1.2" .-> REL
    classDef ptr fill:#eef,stroke:#557;
    class MAIN,REL ptr;

Prose: Work with lanes.

3. The change lifecycle — no staging, auto-snapshot

Every edit flows into the current change continuously; commit finalizes it and starts the next.

stateDiagram-v2
    [*] --> Editing: open working copy
    Editing --> Editing: file save<br/>(auto-tracked in current change)
    Editing --> Committed: tovio commit -m
    Committed --> Editing: next change started automatically
    Committed --> Amended: tovio commit --amend
    Amended --> Committed: same Change ID preserved
    Committed --> Landed: tovio land --into <lane>
    Landed --> [*]
    Editing --> Undone: tovio undo
    Committed --> Undone: tovio undo
    Undone --> Editing

Prose: Commit your work · The change model.

4. tovio commit — what actually happens

Commit is a two-step atomic move: finalize the current change; start a fresh successor. The finalized change keeps its Change ID for life.

sequenceDiagram
    autonumber
    actor Dev as Developer
    participant CLI as tovio-cli
    participant Core as tovio-core
    participant Repo as Repository

    Dev->>CLI: edit files (no `add`)
    CLI->>Core: track edits into current change chg:a3f7b2
    Dev->>CLI: tovio commit -m "Add Dexcom G7 sync"
    CLI->>Core: finalize chg:a3f7b2 (immutable snapshot)
    Core->>Repo: write immutable commit object
    Core->>Repo: start chg:b8e201 (successor)
    Core-->>CLI: ✓ committed a3f7b2 → started b8e201
    CLI-->>Dev: two lines: finalized + new current change

5. Stacking — the everyday shape of in-flight work

You don't feature-branch per unit of work; you stack changes on top of each other. Landing the bottom cascades a rebase up the stack automatically.

flowchart TB
    subgraph STACK[" Your stack "]
        direction TB
        C1["chg:001 — schema"]
        C2["chg:002 — API"]
        C3["chg:003 — UI"]
        C1 --> C2 --> C3
    end
    STACK --> LAND{"tovio land my-lane<br/>--into main"}
    LAND --> MAIN["main advances<br/>to include chg:001"]
    LAND --> CASC[["Automatic rebase cascade:<br/>chg:002, chg:003 re-parented onto main<br/>Change IDs preserved"]]
    CASC --> RESULT["Stack intact:<br/>main ─ chg:002 ─ chg:003"]

Prose: Land a change → cascade.

See it, don't just read it

When several lanes are in flight at once, tovio explain lanes draws them on one timeline — every lane a row, with the fork and merge points marked — so you can see exactly where they branched off and where a land brought them back together.

6. One verb, two regimes — landing onto your own lane vs. a protected lane

Git has merge and a separate "push to the shared branch" step. TOVIO has one integration verb, tovio land <source> --into <target>, and what it does depends on the target. Onto an unprotected lane — your own line of work — the land itself completes even when regions collide: the conflicts are stored on its result and nothing else is blocked. Onto a protected lane the land gates run and the lane will not advance while unresolved conflicts remain. Either way, a later land of a tip that still carries unresolved conflicts is refused, so stored conflicts never travel past the lane that holds them. tovio sync integrates upstream divergence the same way, on the lane.

flowchart LR
    subgraph OWN[" land onto your own lane "]
        M1["Bring another lane's work<br/>into your line of work"] --> M2{"auto-merges?"}
        M2 -- yes --> M3([✓ landed])
        M2 -- no --> M4[["✓ landed<br/>+ typed conflict object stored<br/>(nothing is blocked)"]]
    end
    subgraph LAND[" land onto a protected lane "]
        L1["Ship a finalized change<br/>onto main / release"] --> L4["Run land gates<br/>(conflict-free, review,<br/>required plugins,<br/>policy checks)"]
        L4 --> L5{"all gates pass?"}
        L5 -- yes --> L3([✓ landed])
        L5 -- no --> L6[["✗ Blocked with reason<br/>and next steps"]]
    end
    classDef stop fill:#fdd,stroke:#c33,color:#600;
    class L6 stop;

7. The protected-lane land gate

Landing onto main / release runs a chain of pre-land checks. Any one can block; each produces structured output explaining what failed and what to do next.

flowchart TD
    L["tovio land my-lane --into main"] --> G0["Change health check"]
    G0 --> G1{"conflict-free?"}
    G1 -- no --> B1[["✗ resolve first<br/>(land gate: conflict-free)"]]
    G1 -- yes --> G2{"lane protection<br/>rules satisfied?"}
    G2 -- no --> B2[["✗ e.g. review required"]]
    G2 -- yes --> G3{"required plugins<br/>(pre-land) pass?"}
    G3 -- no --> B3[["✗ plugin blocked land<br/>(see TVO-PLUGIN-009)"]]
    G3 -- yes --> G4{"policy checks<br/>(build-check, attestations)?"}
    G4 -- no --> B4[["✗ policy blocked"]]
    G4 -- yes --> OK([✓ Landed onto main])

    classDef stop fill:#fdd,stroke:#c33,color:#600;
    class B1,B2,B3,B4 stop;

Related: Conflict workflows → land gate · Plugin workflows.

8. Rewriting history — Change IDs persist

commit --amend, rebase, change split, and change absorb rewrite the contents of history but preserve the change identity, so recorded resolutions, reviews, and references remain attached.

flowchart LR
    A["chg:002 (before)<br/>content v1"] --> OP{{"tovio commit --amend<br/>tovio rebase<br/>tovio change split / absorb"}}
    OP --> B["chg:002 (after)<br/>content v2"]
    B --> KEEP1["✓ same Change ID"]
    B --> KEEP2["✓ recorded conflict resolutions still apply"]
    B --> KEEP3["✓ reviews & references still resolve"]
    B --> KEEP4["✓ op-logged — tovio undo reverses it"]

Prose: Rewrite history · Conflict workflows → rerere replay.

9. Sync — pull integration, offline-first

sync is the everyday "catch up with everyone else" verb. It's a merge under the hood: divergence is never an error, and any resulting content forks become stored conflicts on your side.

sequenceDiagram
    autonumber
    actor Dev as Developer
    participant CLI as tovio-cli
    participant Local as Local repo
    participant Remote as Remote / peer

    Dev->>CLI: tovio sync
    CLI->>Remote: fetch new changes & ref moves
    Remote-->>CLI: change objects + CRDT ref updates
    CLI->>Local: apply objects, converge ref pointers (CRDT)
    CLI->>Local: typed 3-way merge for overlapping work
    alt clean
        Local-->>CLI: no new conflicts
        CLI-->>Dev: ✓ up to date
    else content forks
        Local-->>CLI: N conflicts stored on your side
        CLI-->>Dev: ✓ synced — resolve when ready
    end

Prose: Offline & distributed.

10. Undo — every day-to-day verb is reversible

Commit, amend, land (with its cascade), rebase, split, absorb, lane delete, resolve — every one is a single op-logged step you can reverse with tovio undo. tovio explain undo shows the log and what the next undo would restore.

flowchart LR
    OP{"Op just performed"} --> LOG[("op-log entry")]
    OP --> COMMIT["tovio commit"]
    OP --> AMEND["tovio commit --amend"]
    OP --> LAND["tovio land (+cascade)"]
    OP --> REBASE["tovio rebase"]
    OP --> SPLIT["tovio change split"]
    OP --> ABSORB["tovio change absorb"]
    OP --> BDEL["tovio lane -d"]
    OP --> RES["tovio resolve"]
    LOG --> U["tovio undo"]
    U --> BACK([✓ state before op restored])
    U --> R["tovio redo"]
    R --> FWD([✓ re-applied])

Prose: Undo and redo recorded operations.

11. End-to-end: a full day in the loop

The whole loop on one page — start a stack, sync, resolve, land, and see the cascade.

sequenceDiagram
    participant Dev as Developer
    participant CLI as tovio-cli
    participant Core as tovio-core
    participant Repo as Repository

    Dev->>CLI: tovio lane feature/cgm-sync
    CLI->>Core: create CRDT lane pointer
    CLI-->>Dev: created — next: tovio switch feature/cgm-sync

    Dev->>CLI: tovio switch feature/cgm-sync
    CLI->>Core: move HEAD onto the new lane

    Dev->>CLI: edit files (auto-tracked in chg-001)
    Dev->>CLI: tovio commit -m schema
    CLI->>Core: finalize chg-001, start chg-002

    Dev->>CLI: edit and tovio commit -m API
    CLI->>Core: finalize chg-002, start chg-003

    Dev->>CLI: tovio sync
    CLI->>Repo: fetch peers, CRDT ref converge, 3-way merge
    Repo-->>CLI: 1 conflict stored on chg-002
    CLI-->>Dev: synced (resolve when ready)

    Dev->>CLI: tovio resolve src/api/client.ts --theirs
    CLI->>Core: apply Resolution, cache for replay

    Dev->>CLI: tovio land my-lane --into main
    CLI->>Core: run land gates (conflict-free, policy, plugins)
    Core->>Repo: advance main, rebase chg-002, chg-003
    Core-->>CLI: landed and cascade complete
    CLI-->>Dev: main -- chg-002 -- chg-003 (IDs preserved)

Where to go next

Last reviewed September 9, 2026

Suggest an improvement to this page Not for security reports — see disclosure