You see how moving changes from a source Change to a target Change might imply abandoning the source.
Squashing Changes
The way jj squash parameter defaults interact is quite clever.The
basic syntax is:
jj squash -f A -t B FILES
- If you omit the list of files, then all the changes in the Change are moved.
- If you omit either
-for-t, then the Current Change@will be implied.
So:
jj squash -f z
moves the edits from z to your current working copy.
If you do:
jj squash -t x
your edits move to x, no matter where it sits in your history,
either in the past or in the future, in the same branch or
elsewhere.
This technique is truly powerful: it lets you edit something here
and send it somewhere else when you're done.
For example, if you notice an unrelated typo while working on a
feature, fix it on the spot and squash it where it belongs.
Or, say you spot something that needs to be done in a different
branch. You can write the change immediately and then move it there
with a jj squash. In a sense, this is the basic move that lets you
work on multiple features simultaneously.
These moves are so idiomatic that Jujutsu offers a "macro command":
absorb. I'll cover it in the following pages with practical
exercises.
Abandoning Changes
When the source Change is left empty after a move, Jujutsu automatically abandons it. For example, say you have:
$ jj log -r "n::zx"
○ zx
○ v
○ s
○ n
If you squash v into n:
then you end up with:
○ zx
○ s
○ n
What Happens To Messages?
As with Git, Jujutsu always preserves information. If squashing
results in deleting a Change, and that Change has a description,
Jujutsu will stop and interactively let you define one. You will
typically merge all the
original messages into one.
Otherwise, you can always set the message with -m, or use
--use-destination-message / -u.
Quiz Time!
Check out this sloppy mistake:
$ jj show yo- --git
--- a/src/App.js
+++ b/src/App.js
...
+ <button
+ className="square"
+ onClick={handleClic}
...
Oops, Clic instead of Click. Have I fixed it in yo-? Not at all!
I committed a fix on top of it, with the very expressive message "Fix":
$ jj show yo --git
--- a/src/App.js
+++ b/src/App.js
@@ -11,7 +11,7 @@
return (
<button
className="square"
- onClick={handleClic}
+ onClick={handleClick}
>
Terrible. Help me, please: get rid of that noisy yo Change and
make yo correct:
Solution
Solution
One way to do that is:
jj edit yo
jj squash -u
Remember? -u is the short for --use-destination-message.
Or, without moving away from your Current Change:
Just jj squash
If you run the bare jj squash, without any argument, then:
- it will move all the changes (indeed, no files are specified)
- from the Current Change to its parent.
- Should your Current Change have no message, it will be abandoned and a fresh new one will be immediately created.
Say you are on the tip of a branch:
@ sw empty
○ zx Click alternates Xs and Os main
○ v Click sets a X
○ sn Square has state
You code, editing @. Then you run jj squash.
Can you see where this goes? It's the equivalent of having the Git
index!
Let me show you how this works.