Working Copy and Operation Log
The working copy is a change
Your directory is always described by a working-copy change. Before any command reads the repository, oxy snapshots: it compares the files with that change and rewrites the change to match. So the working copy is always recorded, and nothing you type is ever lost.
flowchart LR
Files[Files on disk] -->|snapshot before each command| WCC[Working-copy change<br/>kind = working-copy]
WCC -->|oxy commit -m| C[Normal change<br/>with your message]
C --> New[Fresh working-copy change<br/>on top]
- The working-copy change is never pushed while it is one.
oxy committurns it into a normal change and starts a new one on top.- There is no staging area and no stash. To commit part of your work, name paths or pick hunks:
oxy commit src/ -m "...",oxy commit -i.
Snapshots are fast: a manifest remembers each file's size and modification time, and only files that changed are read.
The operation log
Every command that changes the repository records an operation: the command, and a view of every bookmark, tag and working copy after it.
flowchart BT
o1["op 1: oxy init"]
o2["op 2: oxy commit -m First"] --> o1
o3["op 3: oxy bookmark create test"] --> o2
o4["op 4: oxy commit -m Third"] --> o3
o5["op 5: oxy op restore op 2"] --> o4
o5 -. same view as .-> o2
H([head]) --> o5
oxy undomoves the head back to the operation before, so the last command is as if never run.oxy op restoreandoxy op revertrecord new operations, sooxy undocan take them back too.
oxy op log # every operation, what it changed, its command
oxy --at-op fa21727d log # any read-only command, as things were then
oxy op restore fa21727d # bookmarks and working copy as they were then
oxy op revert fa21727d # undo just that operation, keep the rest
oxy undo # take back the last command
Two processes at once
The operation head moves by compare-and-swap. If two oxy commands run at once, the second finds the head has moved, and records a merge of both views instead of overwriting the first.
sequenceDiagram
participant P1 as oxy commit
participant Head as Operation head
participant P2 as oxy bookmark create
P1->>Head: read head = op 7
P2->>Head: read head = op 7
P2->>Head: swap 7 to 8 (ok)
P1->>Head: swap 7 to 9 (refused: head is 8)
P1->>Head: merge views of 8 and 9 into op 10, swap 8 to 10 (ok)
On a local disk the swap happens under a short lock. For a repository kept in a bucket the bucket's own conditional write does it, see Strata.
A crash leaves the repository at the operation before or after the interrupted command, never between: every object an operation names is written and synced before the head moves.