mirror of
https://github.com/martinvonz/jj.git
synced 2024-11-13 14:15:02 +03:00
59 lines
3.0 KiB
Markdown
59 lines
3.0 KiB
Markdown
|
# Operation log
|
||
|
|
||
|
|
||
|
## Introduction
|
||
|
|
||
|
Jujutsu records each operation that modifies the repo in the "operation log".
|
||
|
You can see the log with `jj op log`. Each operation object contains a snapshot
|
||
|
of how the repo looked at the end of the operation. We call this snapshot a
|
||
|
"view" object. The view contains information about where each branch, tag, and
|
||
|
Git ref (in Git-backed repos) pointed, as well as the set of heads in the repo,
|
||
|
and the current checkout. The operation object also (in addition to the view)
|
||
|
contains pointers to the operation(s) immediately before it, as well as metadata
|
||
|
about the operation, such as timestamps, username, hostname, description.
|
||
|
|
||
|
The operation log allows you to undo an operation (`jj op undo`), which doesn't
|
||
|
need to be the most recent one. It also lets you restore the entire repo to the
|
||
|
way it looked at an earlier point (`jj op restore`).
|
||
|
|
||
|
|
||
|
## Concurrent operations
|
||
|
|
||
|
One benefit of the operation log (and the reason for its creation) is that it
|
||
|
allows lock-free concurrency -- you can run concurrent `jj` commands without
|
||
|
corrupting the repo, even if you run the commands on different machines that
|
||
|
access the repo via a distributed file system (as long as the file system
|
||
|
guarantees that a write is only visible once previous writes are visible). When
|
||
|
you run a `jj` command, it will start by loading the repo at the latest
|
||
|
operation. It will not see any changes written by concurrent commands. If there
|
||
|
are conflicts, you will be informed of them by subsequent `jj st` and/or
|
||
|
`jj log` commands.
|
||
|
|
||
|
As an example, let's say you had started editing the description of a change and
|
||
|
then also update the contents of the change (maybe because you had forgotten the
|
||
|
editor). When you eventually close your editor, the command will succeed and
|
||
|
e.g. `jj log` will indicate that the change has diverged.
|
||
|
|
||
|
|
||
|
## Loading an old version of the repo
|
||
|
|
||
|
The top-level `--at-operation/--at-top` option allows you to load the repo at a
|
||
|
specific operation. This can be useful for understanding how your repo got into
|
||
|
the current state. It can be even more useful for understanding why someone
|
||
|
else's repo got into its current state.
|
||
|
|
||
|
When you use `--at-op`, the automatic snapshotting of the working copy will not
|
||
|
take place. When referring to a revision with the `@` symbol (as many commands
|
||
|
do by default), that will resolve to the current checkout recorded in the
|
||
|
operation's view (which is actually how it always works -- it's just the
|
||
|
snapshotting that's skipped with `--at-op`).
|
||
|
|
||
|
As a top-level option, `--at-op`, it can be passed to any command. However, you
|
||
|
will typically only want to run read-only commands. For example, `jj log`,
|
||
|
`jj st`, and `jj diff` all make sense. It's still possible to run e.g.
|
||
|
`jj --at-op=<some operation ID> describe`. That's equivalent to having started
|
||
|
`jj describe` back when the specified operation was the most recent operation
|
||
|
and then let it run until now (which can be done for that particular command by
|
||
|
not closing the editor). There's practically no good reason to do that other
|
||
|
than to simulate concurrent commands.
|