A **revset** is an expression that selects a set of changes. Mercurial
13
and Jujutsu users know the idea, so Oxygen keeps the name and much of
14
the syntax. People should not have to learn a new language to ask
15
familiar questions.
16
17
Oxygen's model makes revsets more natural than in Git:
18
-History is a set of changes, and a state is itself a set: the
19
dependency closure of its heads. Revsets are set algebra over the
20
dependency graph.
21
- Changes keep their identity across rebases and transport, so a saved
22
revset means the same thing tomorrow.
23
24
Oxygen also has things no other system can query: signatures, delegates,
25
attestations and build receipts. Section 2.4 adds those.
26
27
**Today** no command takes `-r`. Commands take a single change (a
28
ChangeId prefix, a `#hash` prefix or `@`) or a bookmark or tag name.
29
Everything here is new, except that symbols resolve exactly as they do
30
today.
31
32
##2. Syntax
33
34
```sh
35
oxy log -r 'main..feature & author(andy)'
36
oxy log -r 'touches("src/**") & date(-7d..)'
37
```
38
39
###2.1 Symbols
40
41
Symbols resolve in today's order: bookmark names, then tag names, then
42
change prefixes.
43
44
| Symbol | Means |
45
|---|---|
46
|`main`, `v0.3.1`| the heads of that bookmark or tag |
47
|`origin/main`| the heads of a remote-tracking bookmark |
48
|`8c5ea12a`| the change with that ChangeId prefix |
49
|`#fc68459c`| the change with that hash prefix |
50
|`@`| the working copy's base heads |
51
|`all()`, `none()`| every stored change, no change |
52
53
###2.2 Relations
54
55
Each function takes a set and returns a set.
56
57
| Expression | Returns |
58
|---|---|
59
|`deps(X)`| the immediate dependencies of X |
60
|`dependents(X)`| changes that immediately depend on X |
61
|`::X`| X and its whole dependency closure, which is the *state* X names |
62
|`X::`| X and everything that transitively depends on it |
63
|`X::Y`| changes that are both in `X::` and in `::Y`|
64
|`X..Y`|`::Y ~ ::X`: what state Y has that state X lacks. This is what a proposal from X to Y adds. |
65
|`heads(X)`, `roots(X)`| members of X that no other member depends on, and members that depend on no other member |
66
|`independent(X, IN)`| changes in IN that neither depend on X nor are depended on by X: what could ship without X. Only Oxygen can answer this, because changes commute. |
67
|`latest(X, n)`| the n most recent members of X, by hybrid logical clock |
68
69
###2.3 Content and metadata
70
71
| Expression | Selects |
72
|---|---|
73
|`author(P)`| changes whose `author` identity matches name, email or KeyId P |
74
|`description(T)`| changes whose message contains T (`re:` for a regular expression) |
75
|`date(RANGE)`| changes by HLC wall time: `2026-10-01..`, `-7d..`, `..2026-09-30`|
76
|`kind(K)`|`normal`, `resolution` or `working-copy`|
77
|`touches(GLOB)`| changes that edit any node whose path matches GLOB in the evaluation state. Nodes keep their identity through renames, so this follows a file's whole history under any name. |
78
|`conflicts(S)`| changes that contributed atoms to a conflict in state S (default `@`). Conflicts belong to states, not changes. |
79
80
###2.4 Trust: unique to Oxygen
81
82
| Expression | Selects |
83
|---|---|
84
|`signed_by(K)`| changes whose signature or seal is by key or identity K, including a delegate such as an agent key |
85
|`delegated()`| changes signed by a delegate rather than their author |
86
|`unsigned()`| changes with no valid signature or seal |
87
|`revoked()`| changes signed by a key now revoked |
88
|`attested(KIND)`| changes in states carrying an attestation of that kind, such as `tag` or `receipt`|
89
|`built(JOB)`| changes in states with a valid receipt for Flow job JOB |
90
91
For example, `release..main & (unsigned() | revoked())` asks: "is
92
anything about to ship without a trustworthy signature?"
93
94
###2.5 Operators and precedence
95
96
From tightest to loosest:
97
98
1.`::` and `..`
99
2.`~` (difference)
100
3.`&` (intersection)
101
4.`|` (union)
102
103
Parentheses group. Strings with spaces or operators are quoted.
104
`~` is difference, as in Jujutsu. There is no unary not: write `all() ~ X`.
105
106
##3. Where revsets are used
107
108
-**Commands that show history** take `-r`: `log`, `show` (several
109
changes), `verify`, and `diff -r` (the combined edit of a set).
110
-**Commands that act on changes** take `-r` too: `abandon`, the agent
111
workflow's `fold`, and `push -r` (push only these heads). Evaluating
112
the revset never changes anything. A command that acts prints the
113
selected set and refuses to act if it is empty. Above a threshold it
114
asks first, or proceeds with `--yes`.
115
-**The hub API** takes `?r=` on history endpoints, evaluated only over