SwarmOps
ReferenceMcp toolsrevert

Page kind: Reference

revert#

Describes v0.11.0Last changed View as Markdown

Takes back changeset (with since, the first-parent range after since) on target, main by default, by landing its inverse: what the target gained since stays, and a later change to the same lines is E_CONFLICT naming the changeset that made it, nothing recorded. Give a reason; the landed changeset records it and the range (show's reverts and revert_reason). Give idempotency_key to make a retry safe, and expect_target as a full 64-hex id.

Metadata
Since
0.11.0
Mutates
yes
Identity required
yes
Envelope op
revert
Cli command
swarmops revert
Request type
RevertReq
Annotations
{"destructiveHint":false,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false}
Max result chars
null
CLI command
swarmops revert

Input schema#

arguments is a RevertReq: swarmops schema RevertReq prints the type. A field the type does not know is ignored.

FieldTypeRequiredDefaultDescription
changesetstringyesThe range's last changeset: on the target's first-parent chain (else E_INVALID_ARG, details.reason not_on_target). A revision as the caller wrote it, for the store to resolve: a ref name (main, release/1.2), a full 64-hex changeset id or a unique prefix of at least 12 hex digits, or a ref's earlier value: <ref>@{N} the value it held N moves before its current one (@{0} is the current value), <ref>@{at=<unix seconds>} the value set by its newest move recorded at or before that instant (the writer's clock, moves read in journal order); optionally followed by ~N for the N-th first-parent ancestor.
expect_targetstring or nullnoPublish only while the target names this changeset, as a land's.
idempotency_keystring or nullnoMakes a retry safe, as a land's key: the same revert again replays it; the same key for another range is E_INVALID_ARG.
max_attemptsintegerno8How many times to try to publish before failing with E_CAS_RETRY_EXHAUSTED: 1 to 32.
max_conflict_bytesintegerno32768The most bytes of hunk text an E_CONFLICT report carries, as a land's.
messagestring or nullnoThe landed changeset's message. When omitted, Revert <12 hex digits of changeset>: <its title> (a range: Revert <n> changesets <since>..<changeset>), a blank line and the reason.
reasonstringyesWhy: 1 to 4,096 bytes, recorded as the landed changeset's revert_reason metadata, and the default message's body.
sincestring or nullnoWhere the range starts, exclusive: a first-parent ancestor of changeset. When omitted, its first parent, so the range is changeset alone; a root's is the empty tree. At most 256 changesets (E_TOO_LARGE).
targetstringno"main"The ref to land the revert on: main or release/<name>, which must exist.

JSON Schema#

As tools/list gives it: each $ref replaced by its definition, so that it stands alone.

JSON
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "`revert` (CLI `revert`): takes back the first-parent range `(since, changeset]` of `target`\nby a land. The land commits the inverse change on `changeset`, every path the range touched\nset to what `since` held there, and lands it from `changeset`: what\nthe target gained since stays, a later change to the same lines is `E_CONFLICT` naming the\nchangeset that made it, and nothing is recorded then. A range whose changes cancel out, or\none the target took back already, is `E_NOTHING_TO_LAND`. A range whose changesets include\nmerges is taken back against their first parents.",
  "properties": {
    "changeset": {
      "description": "The range's last changeset: on the target's first-parent chain (else `E_INVALID_ARG`,\n`details.reason` `not_on_target`). A revision as the caller wrote it, for the store to resolve: a ref name (`main`,\n`release/1.2`), a full 64-hex changeset id or a unique prefix of at least 12 hex digits, or a\nref's earlier value: `<ref>@{N}` the value it held N moves before its current one (`@{0}`\nis the current value), `<ref>@{at=<unix seconds>}` the value set by its newest move\nrecorded at or before that instant (the writer's clock, moves read in journal order);\noptionally followed by `~N` for the N-th first-parent ancestor.",
      "type": "string"
    },
    "expect_target": {
      "anyOf": [
        {
          "pattern": "^[0-9a-fA-F]{64}$",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Publish only while the target names this changeset, as a land's."
    },
    "idempotency_key": {
      "description": "Makes a retry safe, as a land's key: the same revert again replays it; the same key for\nanother range is `E_INVALID_ARG`.",
      "type": [
        "string",
        "null"
      ]
    },
    "max_attempts": {
      "default": 8,
      "description": "How many times to try to publish before failing with `E_CAS_RETRY_EXHAUSTED`: 1 to 32.",
      "format": "uint32",
      "maximum": 32,
      "minimum": 1,
      "type": "integer"
    },
    "max_conflict_bytes": {
      "default": 32768,
      "description": "The most bytes of hunk text an `E_CONFLICT` report carries, as a land's.",
      "format": "uint64",
      "minimum": 0,
      "type": "integer"
    },
    "message": {
      "description": "The landed changeset's message. When omitted, `Revert <12 hex digits of changeset>:\n<its title>` (a range: `Revert <n> changesets <since>..<changeset>`), a blank line and\nthe reason.",
      "type": [
        "string",
        "null"
      ]
    },
    "reason": {
      "description": "Why: 1 to 4,096 bytes, recorded as the landed changeset's `revert_reason` metadata, and\nthe default message's body.",
      "type": "string"
    },
    "since": {
      "anyOf": [
        {
          "description": "A revision as the caller wrote it, for the store to resolve: a ref name (`main`,\n`release/1.2`), a full 64-hex changeset id or a unique prefix of at least 12 hex digits, or a\nref's earlier value: `<ref>@{N}` the value it held N moves before its current one (`@{0}`\nis the current value), `<ref>@{at=<unix seconds>}` the value set by its newest move\nrecorded at or before that instant (the writer's clock, moves read in journal order);\noptionally followed by `~N` for the N-th first-parent ancestor.",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "Where the range starts, exclusive: a first-parent ancestor of `changeset`. When omitted,\nits first parent, so the range is `changeset` alone; a root's is the empty tree. At most\n256 changesets (`E_TOO_LARGE`)."
    },
    "target": {
      "default": "main",
      "description": "The ref to land the revert on: `main` or `release/<name>`, which must exist.",
      "type": "string"
    }
  },
  "required": [
    "changeset",
    "reason"
  ],
  "title": "RevertReq",
  "type": "object"
}

Annotations#

It adds a changeset onto a ref's head and moves the ref to it, keeping all the ref held. Run again with the same arguments, it finds its change on the ref and adds nothing: replayed with an idempotency_key, E_NOTHING_TO_LAND without.

AnnotationValueMeaning
destructiveHintfalseTrue: a tool that changes the store may overwrite or delete what is there, not only add to it.
idempotentHinttrueTrue: calling it again with the same arguments changes nothing more.
openWorldHintfalseTrue: it reaches beyond a closed set of things. Every tool here stays inside the store.
readOnlyHintfalseTrue: the tool does not change its environment, the store.

Its entry in tools/list carries no _meta.

CLI command#

swarmops revert runs the same operation and prints the same envelope.

Examples#

JSON
{
  "id": 41,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "changeset": "[theirs]",
      "idempotency_key": "revert-1",
      "reason": "the docs were wrong"
    },
    "name": "revert"
  }
}
JSON
{
  "id": 41,
  "jsonrpc": "2.0",
  "result": {
    "content": [
      {
        "text": "{\"api\":1,\"meta\":{\"auth\":\"trust\",\"elapsed_ms\":\"[elapsed_ms]\",\"repo\":\"[tmp]/store\",\"resolved\":{\"[theirs]\":\"[theirs]\",\"main\":\"[id15]\"}},\"ok\":true,\"op\":\"revert\",\"result\":{\"land\":{\"attempts\":1,\"base\":\"[theirs]\",\"files_changed\":1,\"landed\":\"[reverted]\",\"rebased_onto\":\"[id15]\",\"relocated\":false,\"squashed_from\":[\"[id16]\"],\"status\":\"landed\",\"target\":\"main\"},\"reverted\":[\"[theirs]\"]}}",
        "type": "text"
      }
    ],
    "isError": false,
    "structuredContent": {
      "api": 1,
      "meta": {
        "auth": "trust",
        "elapsed_ms": "[elapsed_ms]",
        "repo": "[tmp]/store",
        "resolved": {
          "[theirs]": "[theirs]",
          "main": "[id15]"
        }
      },
      "ok": true,
      "op": "revert",
      "result": {
        "land": {
          "attempts": 1,
          "base": "[theirs]",
          "files_changed": 1,
          "landed": "[reverted]",
          "rebased_onto": "[id15]",
          "relocated": false,
          "squashed_from": [
            "[id16]"
          ],
          "status": "landed",
          "target": "main"
        },
        "reverted": [
          "[theirs]"
        ]
      }
    }
  }
}

The server ran as swarmops mcp --repo [tmp]/store --as agent/worker-17, after initialize. Recorded by the MCP 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, the version.

Return information#

A tool result: the envelope, whose op is revert, as structuredContent and again as the text of its one content block. isError is true exactly when the envelope's ok is false. On success the envelope's result is what swarmops revert returns.

Errors#

A failed call is a tool result with isError: true; the envelope's error.code is one of the error codes.

  • E_INVALID_ARG: arguments that do not fit RevertReq, a field named twice among them included, or that break one of the server's own rules.
  • E_IDENTITY_REQUIRED: the server runs with no identity.
  • E_NOT_A_REPO: the server's store is not there; the server serves on.
  • E_INTERNAL: the operation panicked, a bug.

Then the errors of the operation, as swarmops revert lists them.

See also#

On this page