Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Moving Chunks Around

Goal

In which you send a single a line of a file back to the past.

jj absorb can dispatch multiple edits within a single file to different Changes. So far, you've only learned to use jj squash -f FROM -t TO FILES, which moves all the edits in the given files at once. But moving every edit in a file is not necessarily what you want. Usually you need to be more selective.

See this case, for example:

$ jj show ym --git

    fix name: Square -> Board

diff --git a/src/App.js b/src/App.js

--- a/src/App.js
+++ b/src/App.js

-// Main apication
+// Main application
...
-export default function Square() {
+export default function Board() {

The main goal of the Change was to rename a function from Square() to Board(). Mixed with this, though, I also fixed another typo (again!): apication -> application.

The line // Main apication was introduced by Change rx. Doing:

$ jj squash -f ym -t rx src/App.js

is too coarse, it would drag the Square() -> Board() rename into rx as well, which is not what you want. jj absorb would work, but there are alternatives which give you more control.

Interactively Select Chunks

Use the --interactive / -i option of jj squash:

jj squash -f ym -t rx -i

An interactive editor will open, with which you can select which chunk to include in the squash:

[File] [Edit] [Select] [View]
( ● ) src\App.js

[●] Section 1/2
  [●] - // Main apication ⏎
  [●] + // Main application ⏎
       2 // Display a 3x3 board and let the user ⏎
       3 // play Tic Tac Toe ⏎

[ ] Section 2/2
  [ ] - ⏎
  [ ] - export default function Square() {⏎
  [ ] + ⏎
  [ ] + export default function Board() {⏎
       6   return ( ⏎
       7     <> ⏎
       8       <div className="board-row"> ⏎
             ⋮

You can use the following keys:

KeyPurpose
Up / DownMove up and down
SpaceSelect a line
fFold / unfold a file
cConfirm
qQuit without confirming

You can also use -i to select whole files: that's often a convenient alternative to listing file names in jj squash -f FROM -t TO FILES.

Building On Top Of Squash

By now, you should have got a solid grip on squash. In combination with rebase, it's one of the sharpest tools in the box.

Take a breath and look at the range of operations now at your fingertips. Odd are, you are already doing things you've never attempted with Git. Be proud of yourself.

It's time for you to see the Squash Workflow, a popular, idiomatic Jujutsu workflow. After this, you won't miss Git's index anymore.