# swarmops revert

> Release: 0.11.0 · Last changed: 2026-11-09 · Source: https://github.com/KeiaiLab/SwarmOps/blob/stable/docs/reference/commands/revert.md

Take back a changeset, or a range of a ref's history, by landing its inverse.

The land commits, on REV, every path the range (SINCE, REV\] touched set to what SINCE held there, and lands that change from REV onto the ref: what the ref gained since stays, and a later change to the same lines is E\_CONFLICT (exit 3), naming the changeset that made it, with nothing recorded. The landed changeset records the range as reverts and the reason as revert\_reason; show prints both. Merges in the range are taken back against their first parents.

```yaml
title: "swarmops revert"
description: "Take back a changeset, or a range of a ref's history, by landing its inverse."
group: "write"
since: "0.11.0"
mutates: true
identity_required: true
mcp_tool: "revert"
envelope_op: "revert"
exit_codes: [0, 2, 3]
errors: [E_INVALID_ARG, E_CONFLICT]
syntax: "swarmops revert [OPTIONS] --reason <TEXT> <REV>"
```

## Syntax

```text
swarmops revert [OPTIONS] --reason <TEXT> <REV>
```

## Required arguments

### `REV`

Syntax: `<REV>`.

The changeset to take back, the range's last: on the ref's first-parent chain.

### `--reason`

Syntax: `--reason <TEXT>`.

Why, 1 to 4,096 bytes: recorded, and the default message's body.

## Optional arguments

The command also takes the [global options](../cli.md#global-options).

### `--since`

Syntax: `--since <REV>`.

Take back the range after this first-parent ancestor of REV, at most 256 changesets (default: REV alone).

### `--onto`

Syntax: `--onto <REF>`.
Default: `main`.

The ref to land the revert on: main or a release ref (release/NAME).

### `--key`

Syntax: `--key <KEY>`.

Makes a retry of this land safe: 1 to 64 letters, digits and '-', such as a uuid v7. Make a new one for each change you land, and give it again only to retry that land.

A land with a key first looks down the ref's first parents, to the change's base, for a changeset landed with the same key: one squashed from this HEAD is the land made before, which the land replays (status: replayed) without writing anything; one from another head is E\_INVALID\_ARG. A key not found there is looked for on the other main, release and branch refs: one that landed on another target is E\_INVALID\_ARG too, and details.target names the ref. Without a key, the same land run again finds its change on the ref already: E\_NOTHING\_TO\_LAND.

### `--message`

Syntax: `-m, --message <MSG>`.

The landed changeset's message (default: "Revert", 12 hex digits of REV and its title, then the reason).

### `--expect-target`

Syntax: `--expect-target <ID>`.

Publish only while the ref names this changeset, a full id: one attempt, and a ref that moved is E\_CAS\_MISMATCH with nothing written.

## Examples

### CLI

```sh
swarmops --repo [tmp]/store --as agent/worker-17 revert [a] --reason 'a broke the build' --key revert-1
```

```json
{
  "ok": true,
  "op": "revert",
  "api": 1,
  "result": {
    "reverted": [
      "[a]"
    ],
    "land": {
      "status": "landed",
      "landed": "[reverted]",
      "rebased_onto": "[b]",
      "target": "main",
      "base": "[a]",
      "attempts": 1,
      "relocated": false,
      "files_changed": 1,
      "squashed_from": [
        "[inverse]"
      ]
    }
  },
  "meta": {
    "repo": "[tmp]/store",
    "elapsed_ms": "[elapsed_ms]",
    "resolved": {
      "[a]": "[a]",
      "main": "[b]"
    },
    "auth": "trust"
  }
}
```

Exit code 0. Recorded by the CLI tests. A name in square brackets, such as `[tmp]` or `[c1]`, stands for what differs from run to run: the test's temporary directory, an id, a time.

### MCP

No recorded example yet.

## Return information

`result` is a `RevertResp` (`swarmops schema RevertResp` prints its JSON Schema).

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `land` | `LandResp` | yes | The land: `squashed_from` holds the one changeset it committed, the inverse change. |
| `reverted` | `array of string` | yes | The changesets taken back, oldest first, as the landed changeset's `reverts` records them. |

Envelope `op`: `revert`.

Exit codes:

- `0`: Success.
- `2`: The request or the command line is malformed.
- `3`: The change conflicts with what it lands on: resolve it, then run the operation again.

## Errors

- [`E_INVALID_ARG`](../errors.md#e_invalid_arg) (exit 2): A malformed argument or request, including a command-line usage error.
- [`E_CONFLICT`](../errors.md#e_conflict) (exit 3): The change conflicts with the target: `details.report` lists each conflicting file with its kind, its hunks and who changed it on the target.

Any command that opens a store may also fail with a store error, such as [`E_NOT_A_REPO`](../errors.md#e_not_a_repo), [`E_IO`](../errors.md#e_io) or [`E_STORE_CORRUPT`](../errors.md#e_store_corrupt); a command line the grammar refuses is [`E_INVALID_ARG`](../errors.md#e_invalid_arg) (exit 2).

## See also

- [`swarmops commit`](commit.md)
- [`swarmops land`](land.md)
- [`swarmops land-check`](land-check.md)
- [`swarmops land-group`](land-group.md)
- [`swarmops rebase`](rebase.md)
- [`swarmops blob put`](blob-put.md)
- [`swarmops blob has`](blob-has.md)
- [CLI reference](../cli.md)
- [Error codes](../errors.md)
