120 lines
4.6 KiB
Markdown
120 lines
4.6 KiB
Markdown
# Recovery
|
|
|
|
Commands for undoing mistakes, resolving conflicts, and restoring lost work.
|
|
|
|
## jj undo
|
|
|
|
Undoes the most recent operation. This is the first recovery command to reach for.
|
|
|
|
```
|
|
jj undo # undo last operation
|
|
jj undo --undo # undo the undo (same as jj redo)
|
|
```
|
|
|
|
Any operation can be undone — commit, rebase, push, etc. The undo itself creates a new operation, so it can also be undone.
|
|
|
|
## jj redo
|
|
|
|
Redo the most recently undone operation.
|
|
|
|
```
|
|
jj redo # redo last undo
|
|
```
|
|
|
|
## jj op log / jj operation
|
|
|
|
View the operation log — the history of all jj commands run in this repo. This is jj's equivalent of shell history but tied to repo state.
|
|
|
|
```
|
|
jj op log # show all operations
|
|
jj op log -n 20 # show last 20 operations
|
|
```
|
|
|
|
Each operation has an ID (hash). The most recent operation is shown at the top with `@`. The snapshot of the working copy is also an operation.
|
|
|
|
## jj op restore
|
|
|
|
Restore the repo to a previous state by operation. Unlike `jj undo` (which only undoes the last operation), this can jump to any point in the operation log.
|
|
|
|
```
|
|
jj op restore OP_ID # restore repo to state after OP_ID
|
|
jj op restore --what undo # restore just the undo history (not working copy)
|
|
```
|
|
|
|
This is *not* a revert — it moves the entire repo state backward (or forward). Changes made after that operation will appear as divergent changes. Use `jj --at-op` for read-only inspection first.
|
|
|
|
## jj restore (content restore)
|
|
|
|
Restore file contents within a revision. This is NOT the same as `jj op restore`.
|
|
|
|
```
|
|
jj restore # restore all files in @ from its parent
|
|
jj restore PATH # restore specific files in @ from its parent
|
|
jj restore --from SOURCE # restore from a specific source revision
|
|
jj restore --changes-in REV # undo the changes introduced by REV (creates reverse diff on @)
|
|
```
|
|
|
|
- Without `--from`: restores from the parent of the target revision
|
|
- Without `--into`: restores into `@`
|
|
- `--changes-in REV` is the closest equivalent to `git revert REV` — it applies the reverse of REV's diff to `@`
|
|
- `--restore-descendants`: when rebasing descendants, preserve their content (not their diff)
|
|
|
|
To "unstage" files (there's no real staging area in jj, but for git users who ask): use `jj restore PATH` to undo changes to specific files in `@`.
|
|
|
|
## jj resolve
|
|
|
|
Resolve merge conflicts. jj tracks conflicts natively (unlike git, which leaves conflict markers in files and lets you handle them).
|
|
|
|
```
|
|
jj resolve PATH... # resolve conflicts in specific files
|
|
jj resolve --list # list all unresolved conflicts
|
|
```
|
|
|
|
When you run `jj resolve`, jj opens the external merge tool (configured in `merge-tools`). If no tool is configured, it falls back to leaving conflict markers in the file, which you can edit manually.
|
|
|
|
After resolving conflicts manually (by editing the file), mark them as resolved with `jj resolve PATH`.
|
|
|
|
## jj --at-op (read-only inspection)
|
|
|
|
Run any jj command as if the repo were at a past operation. Read-only — useful for inspecting old state before deciding whether to restore.
|
|
|
|
```
|
|
jj --at-op OP_ID log # log from past state
|
|
jj --at-op OP_ID status # status from past state
|
|
jj --at-op OP_ID diff -r REV # diff from past state
|
|
```
|
|
|
|
## Divergent changes
|
|
|
|
When the operation log has diverged (e.g., two concurrent operations), `jj status` will warn about divergent operations. This happens when you run jj commands from different terminals or after `jj op restore`.
|
|
|
|
To resolve divergence:
|
|
1. `jj --at-op OP_ID status` for each divergent operation to understand the state
|
|
2. `jj op restore` to pick one side
|
|
3. Or use `jj new` to create a merge of the divergent states
|
|
|
|
## Common recovery scenarios
|
|
|
|
**"I rebased and lost changes"**
|
|
- `jj undo` — undoes the rebase
|
|
- If `jj undo` isn't enough: `jj op log` to find the pre-rebase operation, then `jj op restore OP_ID`
|
|
|
|
**"I pushed the wrong thing"**
|
|
- You can't unpush (remote doesn't support it), but you can:
|
|
1. Fix the local revision
|
|
2. `jj bookmark move --to=FIXED BOOKMARK`
|
|
3. `jj git push --force` or `jj git push` with a new commit
|
|
|
|
**"I accidentally squashed the wrong files"**
|
|
- `jj undo` immediately
|
|
- If too late: use the operation log to find the pre-squash state
|
|
|
|
**"I want to get old version of a file back"**
|
|
- `jj restore --from OLD_REV PATH` — restore PATH from OLD_REV into `@`
|
|
- Or: `jj file show -r OLD_REV PATH > PATH` to extract it as a file
|
|
|
|
**"jj status shows conflicts"**
|
|
- `jj resolve --list` to see which files have conflicts
|
|
- Resolve them individually: `jj resolve PATH`
|
|
- After resolving all, `jj status` will clear
|