Bookmarks
A bookmark is a named pointer to a state, like a Git branch. Each workspace works on one bookmark at a time; main to begin with.
The big difference from Git: merging is just a union. A state is a set of changes, so merging feature into main adds feature's heads to main's. There is no merge commit. A real conflict is recorded in the state, as described in Conflicts.
flowchart LR
subgraph before[Before oxy merge feature]
M1[main: heads A, B]
F1[feature: heads A, C]
end
subgraph after[After]
M2[main: heads A, B, C]
end
M1 --> M2
F1 --> M2
A feature flow
sequenceDiagram
participant You
participant main
participant feature as feature/42-login
You->>feature: oxy bookmark create feature/42-login
You->>feature: oxy bookmark switch feature/42-login --carry
You->>feature: oxy commit -m "Login form"
You->>feature: oxy push -b feature/42-login
You->>main: oxy bookmark switch main
You->>main: oxy merge feature/42-login
Note over main: main now holds the feature's changes,<br/>no merge commit
You->>main: oxy push
oxy bookmark create feature/42-login
oxy bookmark switch feature/42-login --carry # take uncommitted edits along
oxy commit -m "Login form"
oxy push -b feature/42-login
oxy bookmark switch main
oxy merge feature/42-login
oxy push
oxy bookmark delete feature/42-login
bookmark switch stops if you have uncommitted edits, so nothing is lost by accident. --carry takes them along, and --discard drops them.
A state is its heads, not a history
This is the one thing to unlearn from Git. A bookmark holds its heads and everything they depend on. A change depends only on the changes it builds on (the lines and files it touched), not on everything recorded before it.
flowchart BT
A[A: add README]
B[B: edit parser.rs] --> A2[A2: add parser.rs]
C[C: edit README] --> A
subgraph main
A
A2
B
C
end
Here main has two heads, B and C. A new bookmark at B alone holds only A2 and B, so its tree has no README. oxy bookmark create NAME CHANGE warns when that would leave work out, and offers:
--upto: everything up to that change, as a Git branch would be;--only: just that change and what it depends on.
Remote bookmarks
A clone checks out the remote's default bookmark and names the others origin/NAME. Use them anywhere a bookmark is expected:
oxy log origin/develop
oxy diff main origin/develop
oxy bookmark switch develop # makes a local develop from origin/develop
oxy pull # updates every local bookmark the remote also has
Pulling is a union, so it never loses work.