> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Apply and rebase

> Replay the operations you invoked on a branch onto live, or onto a fresh fork of live

<Warning>Branches are in beta.</Warning>

Data leaves a branch only by **replay**. Applying a branch doesn't copy its
documents to live. It runs the [operations](/operations/overview) you invoked
on the branch again, on live, in the order they committed. Each one runs
against live's current data and under your current permissions, so live's
rules decide the outcome, exactly as if you had invoked it there.

```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
bijection branch apply what-if --identity '{ tokenIdentifier: "issuer|alice" }'
bijection branch apply what-if --identity '{ tokenIdentifier: "issuer|alice" }' --commit
```

## What replay carries

Replay selects the operations that one identity invoked directly on the branch,
and that have not been applied yet. Pass that identity with `--identity`, as you
did when you [ran them](/branches/lifecycle#running-functions-and-operations-on-a-branch).
Another user applies their own operations.

Everything else stays on the branch, and the report says so:

* changes made by ordinary [mutations](/functions/mutation-functions), by
  console edits or by imports;
* operations called from inside a mutation or an action;
* work done on the branch by scheduled functions, crons or other users.

<Tip>
  If you want an edit to be appliable, expose it as an operation.
</Tip>

## Applying to live

<Steps>
  <Step title="Preview">
    Without `--commit`, `apply` runs every step in one transaction on live and
    throws the transaction away. Nothing changes on live.

    ```text Output theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
    Preview onto live: 2 step(s), not applied
      ok       items:add <invocation ID> (1 id(s) remapped)
      ok       items:setQty <invocation ID>
    Nothing was applied. Run `bijection branch apply what-if --commit` to apply.
    ```
  </Step>

  <Step title="Commit">
    With `--commit`, `apply` previews first and commits only if no step was
    refused or diverged. The commit is all or nothing: every step commits in
    one transaction, or none does.
  </Step>
</Steps>

Each step has a status:

| Status | Meaning |
| - | - |
| `ok` | The operation replays on live. |
| `refused` | The operation can't be replayed. The reason is shown beside it. |
| `diverged` | The operation ran on live but did something different than on the branch. |
| `skipped` | The operation waits for a later apply. |

A refused or diverged step stops the whole apply, and `apply` exits with an
error.

### Applying again

Applying is incremental. Each operation on the branch is applied to live at
most once, and applying again continues after the last applied one. `bijection
branch status` shows how far the identity has applied, under `Applied:`.

One apply runs at most 128 operations. When more remain, the report says how
many, and you apply again to continue.

Two applies of the same operations at the same time conflict, and only one
commits.

### Documents created on the branch

A document created on the branch gets a different ID on live. Replay matches
each document an operation created on the branch with the one it creates on
live, and rewrites later arguments that name it through their `v.id(...)`
[validators](/functions/validation). The report shows each remapped ID.

For this to be safe, replay refuses an operation:

* whose arguments are declared with `v.any()`, because IDs inside it can't be
  found;
* whose argument is a plain string equal to an ID created on the branch;
* that creates a different number of documents on live than on the branch.
  That step is `diverged`.

### Changed code

Replay refuses an operation whose definition on live differs from the branch.
If you changed code on the branch, deploy it to live first, then apply.

An operation whose recorded arguments have since expired is refused as well.

### External calls

External calls are held on a branch and are never delivered from it. When you
apply, live's replay of an operation requests its external calls again, as new
calls that live delivers the ordinary way. The local changes of an apply commit
together, but each external call then succeeds or fails on its own. Discarding
the branch afterwards does not undo them, and reversing a delivered call is a
separate operation.

If an applied operation's external call had an assumed result on the branch,
the operations after it may depend on that result. Apply stops after that
operation:

```text Output theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
Commit onto live: 2 step(s), applied
  ok       accounts:rename <invocation ID>
  skipped  items:add <invocation ID>
Applied 1 step(s); 1 wait for invocation <invocation ID>'s external calls to be confirmed on live. Apply again later to continue.
```

Apply again once live has confirmed the call. Until then, apply runs nothing.
If the call on live is refused, not applied, or its outcome is unknown, further
applies are refused. Rebase or discard the branch instead.

## Rebasing

A branch never sees live's changes after its basis. To bring your work up to
date, rebase it:

```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
bijection branch rebase what-if what-if-2 --identity '{ tokenIdentifier: "issuer|alice" }'
```

`rebase` creates a new branch of live at its current revision, named by the
second key, and replays onto it the operations of this identity that you
haven't applied to live yet. Their external calls are held again on the new
branch. The old branch is kept.

* Only a branch of live can be rebased.
* The new key must not already name a branch.
* All remaining operations replay in one transaction. More than 128 are
  refused rather than rebased in part.
* If the replay is refused or diverges, the new branch is discarded.

Pass `--show-admin-key` to print the new branch's admin key.
