Page kind: Reference
ref_txn#
Moves 1 to 64 refs as one operation, each by compare-and-swap, all of them or none: each move names its ref, expect (the full 64-hex changeset id it holds when you read it; omitted to create it) and to (omitted to delete it). Every expectation is checked first: any stale one is E_CAS_MISMATCH, every failed ref in details.mismatches, nothing written. undo of its id restores every ref at once.
- Since
0.11.0- Mutates
- yes
- Identity required
- yes
- Envelope op
ref_txn- Cli command
swarmops ref txn- Request type
RefTxnReq- Annotations
{"destructiveHint":true,"idempotentHint":true,"openWorldHint":false,"readOnlyHint":false}- Max result chars
null- CLI command
swarmops ref txn
Input schema#
arguments is a RefTxnReq: swarmops schema RefTxnReq prints the type. A field the type does not know is ignored.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
moves | array of object | yes | The moves: 1 to 64 (E_INVALID_ARG for none, E_TOO_LARGE past 64), each ref once. |
JSON Schema#
As tools/list gives it: each $ref replaced by its definition, so that it stands alone.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "`ref_txn` (CLI `ref txn`): move several refs as one operation, each by compare-and-swap, all\nof them or none. Every expectation is checked under the store's lock\nbefore any move is made: one or more that fail make it `E_CAS_MISMATCH`, every failed ref in\n`details.mismatches`, and nothing is written. Each move follows `ref set`'s and `ref\ndelete`'s rules: `main` only along its first parents and never deleted (`E_REF_PROTECTED`), a\ntag never moved (`E_TAG_IMMUTABLE`), no remote-tracking ref (`E_REF_NAME_INVALID`).",
"properties": {
"moves": {
"description": "The moves: 1 to 64 (`E_INVALID_ARG` for none, `E_TOO_LARGE` past 64), each ref once.",
"items": {
"description": "One move of a `ref_txn`: ref `name` from `expect` to `to`. A move that changes nothing\n(`expect` and `to` the same, or both omitted) is `E_INVALID_ARG`.",
"properties": {
"expect": {
"anyOf": [
{
"pattern": "^[0-9a-fA-F]{64}$",
"type": "string"
},
{
"type": "null"
}
],
"description": "The target the caller last saw, by its full changeset id, as `ref set`'s `expected_old`;\nomitted to create the ref, which must not exist."
},
"name": {
"description": "The ref: `main`, `release/<name>` or a tag.",
"type": "string"
},
"to": {
"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": "The revision to point it at; omitted to delete it."
}
},
"required": [
"name"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"moves"
],
"title": "RefTxnReq",
"type": "object"
}Annotations#
It moves or deletes refs by compare-and-swap, changing what they name. Run again with the same arguments, it finds them as it asked (already_applied) or not as it expected (E_CAS_MISMATCH), and changes nothing more.
| Annotation | Value | Meaning |
|---|---|---|
destructiveHint | true | True: a tool that changes the store may overwrite or delete what is there, not only add to it. |
idempotentHint | true | True: calling it again with the same arguments changes nothing more. |
openWorldHint | false | True: it reaches beyond a closed set of things. Every tool here stays inside the store. |
readOnlyHint | false | True: the tool does not change its environment, the store. |
Its entry in tools/list carries no _meta.
CLI command#
swarmops ref txn runs the same operation and prints the same envelope.
Examples#
{
"id": 45,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"moves": [
{
"name": "release/a",
"to": "[c1]"
},
{
"name": "release/b",
"to": "[c1]"
}
]
},
"name": "ref_txn"
}
}{
"id": 45,
"jsonrpc": "2.0",
"result": {
"content": [
{
"text": "{\"api\":1,\"meta\":{\"auth\":\"trust\",\"elapsed_ms\":\"[elapsed_ms]\",\"repo\":\"[tmp]/store\",\"resolved\":{\"[c1]\":\"[c1]\"}},\"ok\":true,\"op\":\"ref_txn\",\"result\":{\"id\":\"18:[crc]\",\"moves\":[{\"actor\":\"agent/worker-17\",\"at\":\"[at]\",\"name\":\"release/a\",\"new\":\"[c1]\"},{\"actor\":\"agent/worker-17\",\"at\":\"[at]\",\"name\":\"release/b\",\"new\":\"[c1]\"}],\"op\":18}}",
"type": "text"
}
],
"isError": false,
"structuredContent": {
"api": 1,
"meta": {
"auth": "trust",
"elapsed_ms": "[elapsed_ms]",
"repo": "[tmp]/store",
"resolved": {
"[c1]": "[c1]"
}
},
"ok": true,
"op": "ref_txn",
"result": {
"id": "18:[crc]",
"moves": [
{
"actor": "agent/worker-17",
"at": "[at]",
"name": "release/a",
"new": "[c1]"
},
{
"actor": "agent/worker-17",
"at": "[at]",
"name": "release/b",
"new": "[c1]"
}
],
"op": 18
}
}
}
}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 ref_txn, 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 ref txn 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
RefTxnReq, 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 ref txn lists them.
See also#
ref_set
Moves a ref, or creates one, by compare-and-swap: give create, or expected\_old, the full 64-hex changeset id the ref held when you read it; a ref name or a…
remote_list
The git remotes the store records: each one's name, URL, followed branch and the token variable it names, if any. Adding and removing remotes is the CLI's.