Skip to content
bay
How it worksFleetRoadmapDocsBlogGitHub ↗
Early access
Docs menu

Start here

  • Overview
  • Install
  • Quickstart
  • Concepts

Land changes

  • Executors
  • Undo a landing
  • Configuration

Coordinate agents

  • Agents and hooks
  • See what your fleet is doing
  • Talk to other actors

Operate bay

  • Host a trunk without a forge
  • Keys and the registry
  • Update

Reference

  • CLI reference
  • Results and refusals
  • Changelog

Start here

  • Overview
  • Install
  • Quickstart
  • Concepts

Land changes

  • Executors
  • Undo a landing
  • Configuration

Coordinate agents

  • Agents and hooks
  • See what your fleet is doing
  • Talk to other actors

Operate bay

  • Host a trunk without a forge
  • Keys and the registry
  • Update

Reference

  • CLI reference
  • Results and refusals
  • Changelog

Land changes

Undo a landing

Take one landed change back out of trunk with a new checked change, and keep trunk's history as it is.

bay is in development. These pages describe bay as it will ship.

bay undo reverses the effect of one landed change. It opens a new change that takes that landing's edits back out of current trunk. The new change runs the same checks and lands like any other change. Use it when a landing breaks something and a fix would take longer.

An undo never rewrites trunk. Every commit before it stays as it was. The undo lands as a new commit with a Reverts: trailer that names the undone change.

When to use undo

  • A red after landing: a check that runs after landing fails, and one change caused it.
  • A wrong landing: a change reached trunk that should not have.
  • Bring a change back: undo the undo, and the original edits return.

Undo a change

Name the landed change. bay returns at once with queued, and an executor finishes the landing.

sh
bay undo c7k2m4

Wait for the outcome

--wait runs the work here and returns its outcome, as bay land --wait does. bay undo has no --observe.

sh
bay undo c7k2m4 --wait

Repair a conflict

Later changes may have edited the same lines. Then the undo does not merge, and bay returns MERGE_CONFLICT. bay leaves the undo change open. detail.view names its view, with conflict markers in the files. Resolve the paths in detail.conflicts, then land the undo from that view.

sh
cd <detail.view>
# resolve each path in detail.conflicts
bay land --wait

How an undo works

  1. 01

    Find the landing

    bay asks the remote for the landed marker refs/bay/landed/<change>. It then finds that landing commit on trunk.

  2. 02

    Build the reverse

    bay merges the reverse of that commit onto current trunk with git merge-tree. When the result equals trunk's own tree, the effect is already gone. bay opens no change.

  3. 03

    Open the undo change

    bay opens a new change on the intent undo of <change>. Its paths are the paths that the landing touched. bay writes the reverse into the view of that change.

  4. 04

    Land

    The undo change takes the normal path to trunk, with the same required checks. Its landing commit carries Reverts: <change>.

Undo the same change twice

  • Each undo of one change claims the next generation of the intent undo of <change>.
  • A second undo waits for the first one to land. Before that, bay refuses it with CHANGE_SUPERSEDED.
  • The second undo also carries a Supersedes: trailer that names the first undo.
  • An undo never claims a generation of the undone change's own intent.

Results

ok, landed and queued exit 0. blocked exits 10, and failed exits 20.

ResultWhen`detail`
queuedWithout --wait: the undo change is open and waits for an executor.As for bay land.
landedWith --wait: the undo landed.As for bay land --wait.
okThe effect is already gone from trunk. bay opens no change, so the result has no change.undo: "nothing to undo", reverts, trunk
blocked, CHANGE_NOT_LANDEDThe change is not on trunk.trunk
blocked, MERGE_CONFLICTThe reverse does not merge onto trunk. The view stays open for repair.conflicts, view, reverts, trunk
failedbay cannot read the remote, so it cannot tell whether the change landed.A string that says why.

A remote that bay cannot read is never CHANGE_NOT_LANDED. The undo change can also meet any refusal of bay land.

What an undo cannot do

  • It cannot remove a commit from trunk. Trunk stays append-only.
  • It cannot skip the checks. The undo is an ordinary change.
  • It cannot undo a change that is not on trunk. Abandon that change instead.
  • It undoes one change per call. Run it once for each change.

Refusals

Each refusal is blocked and exits 10. The Results page lists what to do next for each one.

CodeMeaning
CHANGE_NOT_LANDEDThe named change is not on trunk.
MERGE_CONFLICTThe reverse does not merge onto current trunk. detail.view holds it for repair.
CHANGE_SUPERSEDEDAn earlier undo of the same change has not landed yet.
← PreviousExecutorsNext →Configuration

On this page

  • When to use undo
  • Undo a change
  • Wait for the outcome
  • Repair a conflict
  • How an undo works
  • Undo the same change twice
  • Results
  • What an undo cannot do
  • Refusals
how it worksfleetroadmapblog© 2026 bay contributors · MIT
Built by Gudjon Gudjonsson, founder and CEO of OZ →Sponsored by OZ