The History Beneath the History
Important
You travel your repository back in time, all the way to when you cloned it.
If every Change has its own history, your whole repository must have one too. It’s only logical:
- Initially (
000000000000), it didn’t exist. - Then it was created.
- Then you added a Change.
- Then you edited a description.
Jujutsu remembers everything: almost every command triggers a working-copy snapshot. You can inspect this meta-history with:
jj op log
○ 281b30d872a3 arialdo@mbuto default@ 3 hours ago, lasted 4 milliseconds
│ remove git remote origin
│ args: jj git remote remove origin
○ 8eea9aa811a1 arialdo@mbuto default@ 3 hours ago, lasted 14 milliseconds
│ check out git remote's branch: main
│ args: jj git clone https://codeberg.org/arialdo/jj-playground.git
○ eff465d67569 arialdo@mbuto default@ 3 hours ago, lasted 2 seconds
│ fetch from git remote into empty repo
│ args: jj git clone https://codeberg.org/arialdo/jj-playground.git
○ ee32fa88d5f2 arialdo@mbuto default@ 3 hours ago, lasted 3 milliseconds
│ add git remote origin
│ args: jj git clone https://codeberg.org/arialdo/jj-playground.git
○ 23c04169eec1 arialdo@mbuto 3 hours ago, lasted 6 milliseconds
│ add workspace 'default'
○ 000000000000 root()
Can you envision what this is? It’s the repository of your repository’s history!
Rewind!
Restoring your repo exactly as it was before an operation is
trivial. Everything originates from 000000000000, each command
creates a full snapshot with its ID. Feed that ID to jj op restore
and you jump back to that exact moment.
Warning
You want to go back to when you performed:
jj git clone https://codeberg.org/arialdo/jj-playground.git cd jj-playground jj bookmark track '*'
Tip
- Run
jj op log.- Find the item for
git remote remove origin. It should be the 5th operation from000000000000.- Copy its ID and run:
jj op restore <ID>Spot on? Congrats!
You could also use:
jj op restore 000000000000+++++to indicate the 5th operation (
+++++) after000000000000.
Check the file system and log: you’re back to when you cloned the repo. Here’s the 3rd option we mentioned before.
Like Emacs, Jujutsu Never Forgets
Check jj op log again. You will find a record for the jj op restore you have just run. Yep! Even going back in time is tracked
down. This lets you undo an undo by restoring its parent. Or, simply:
this is what jj redo does.
Basically:
- Every operation (including
restoreandundo) appends a snapshot to the op log. op restoreapplies an old snapshot and appends the result to history.undorestores the previous op.
We’ve all dreaded performing risky Git operations. I hope that armed with these tools, you’ll never feel that way again.
Ready For The Next Chapter?
Run:
jj op restore 000000000000+++++
Makes all Changes of main mutable running this extra command:1
jj config set --repo 'revset-aliases."trunk()"' 'none()'
Your repo should be:
○ qn Add the CSS file **css**
○ rt Link to CSS
│ ○ o Play instructions **manual**
│ ○ kx Play manual
├─╯
│ ○ zx Click alternates Xs and Os **dev**
│ ○ v Click sets a X
│ ○ s Square has state
├─╯
○ qq Fix
○ n Square is interactive
○ ru Board() invokes Square()
├─╮
○ │ ym fix name: Square -> Board
○ │ x WIP delete me
○ │ yz LICENSE
○ │ ws A board full of X
├─╯
○ kk Displays X X **main**
○ wx Fails
○ rx Scaffold applicatio
◆ zz 🔒 ▢
Good. You’re ready to play with rebase and squash.
-
Jujutsu keeps the Changes of trunk (
main) immutable by default. It’s a safety net against rewriting published commits. We’re about to rewrite history on purpose so we can turn that guardrail off instructing Jujutsu that we don’t have a trunk.
You’ll see that safety net at work when we talk about remotes. I promise: it’s amazing. ↩