Skip to content

Commit 2587de2

Browse files
committed
add chapter about commit --interactive
1 parent ae3d0d8 commit 2587de2

File tree

10 files changed

+214
-36
lines changed

10 files changed

+214
-36
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
- [Resolving merge conflicts](./conflict.md)
3636
- [Deleting commits and bookmarks](./abandon.md)
3737
- [Restoring file contents](./restore.md)
38+
- [Split a messy working copy](./commit_interactive.md)
3839

3940
- [Must-know secret commands](./to_be_continued.md)
4041

src/clone.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ We can tell Jujutsu to show us _all_ commits with `jj log --revisions 'all()'`:
7272

7373
Both of our commits are here, so our repository was successfully restored from the remote.
7474

75+
##
76+
7577
```admonish success title="You've completed Level 1 ! 🎉"
7678
You made it!
7779
At this point, you have all the skills needed for simple solo projects with proper backup.

src/commit_interactive.md

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# Split a messy working copy
2+
3+
````admonish reset title="Reset your progress" collapsible=true
4+
To reset your progress to the start of this chapter, run the following command:
5+
6+
```sh
7+
curl https://jj-for-everyone.github.io/reset.sh | bash -s commit_interactive
8+
cd ~/jj-tutorial/repo
9+
```
10+
````
11+
12+
Recall the basic workflow we learned at the [very beginning](./commit.md):
13+
14+
1. make some changes
15+
2. create a new commit
16+
17+
...repeat.
18+
This is fine, but Alice is unfortunately a little forgetful.
19+
(Aren't we all?)
20+
Every once in a while, Alice makes a bunch of changes that are unrelated to each other, while forgetting to create a new commit in between.
21+
Let's see how that could look like.
22+
23+
Assume Alice needs to complete three tasks.
24+
Task 1 is implemented in its own file, while tasks 2 and 3 are implemented in the same file:
25+
```sh
26+
echo "Implement task 1" > task_1.txt
27+
echo "Implement task 2" > tasks_2_and_3.txt
28+
echo "Implement task 3" >> tasks_2_and_3.txt
29+
```
30+
31+
<!-- generated by aha script -->
32+
<pre class="aha">
33+
Commit ID: <span class="blue ">84ea100fcd1065a3edbdf1bc0dda2dc9446b147e</span>
34+
Change ID: <span class="purple ">pnwmqvrumpqkovqowswpxpuqnuospkxo</span>
35+
Author : <span class="yellow ">Alice</span> &lt;<span class="yellow ">alice@local</span>&gt; (<span class="cyan ">2025-11-06 15:37:35</span>)
36+
Committer: <span class="yellow ">Alice</span> &lt;<span class="yellow ">alice@local</span>&gt; (<span class="cyan ">2025-11-06 15:37:35</span>)
37+
38+
<span class="yellow "> (no description set)</span>
39+
40+
<span class="yellow ">Added regular file task_1.txt:</span>
41+
<span class="green "> 1</span>: <span class="underline "></span><span class="underline green ">Implement task 1</span><span class="green "></span>
42+
<span class="yellow ">Added regular file tasks_2_and_3.txt:</span>
43+
<span class="green "> 1</span>: <span class="underline "></span><span class="underline green ">Implement task 2</span><span class="green "></span>
44+
<span class="green "> 2</span>: <span class="underline "></span><span class="underline green ">Implement task 3</span><span class="green "></span>
45+
</pre>
46+
47+
Alice could make a commit with the description "Implement tasks 1, 2 and 3".
48+
That would be fine in most situations.
49+
But sometimes, especially if these tasks are complex and require a lot of changes, it can be a mess.
50+
Putting them all in the same commit makes it harder to understand how the project evolved later on, both by Alice herself and other people like Bob.
51+
Lastly, if Alice makes a mistake while implementing, say, task 2, it is more difficult to revert the mistake without also losing the improvements made by tasks 1 and 3.
52+
53+
If Alice wants to have those tasks in separate commits, how can she do that?
54+
55+
## Committing only certain files
56+
57+
The first option we'll look at is commit only certain files of the working copy.
58+
This works for task 1, which is isolated to its own file.
59+
To achieve this, you just pass the names of the files to commit as arguments to `jj commit`:
60+
61+
```sh
62+
jj commit --message "Implement task 1" task_1.txt
63+
```
64+
65+
Let's inspect the commit produced by this command with `jj show @-`:
66+
67+
<!-- generated by aha script -->
68+
<pre class="aha">
69+
Commit ID: <span class="blue ">728297d2218d393b98f88638697f19c75a88a906</span>
70+
Change ID: <span class="purple ">pnwmqvrumpqkovqowswpxpuqnuospkxo</span>
71+
Author : <span class="yellow ">Alice</span> &lt;<span class="yellow ">alice@local</span>&gt; (<span class="cyan ">2025-11-06 15:37:35</span>)
72+
Committer: <span class="yellow ">Alice</span> &lt;<span class="yellow ">alice@local</span>&gt; (<span class="cyan ">2025-11-06 15:47:11</span>)
73+
74+
Implement task 1
75+
76+
<span class="yellow ">Added regular file task_1.txt:</span>
77+
<span class="green "> 1</span>: <span class="underline "></span><span class="underline green ">Implement task 1</span><span class="green "></span>
78+
</pre>
79+
80+
Splendid!
81+
And what does our current working copy commit look like?
82+
Let's check with `jj show`:
83+
84+
<!-- generated by aha script -->
85+
<pre class="aha">
86+
Commit ID: <span class="blue ">a0631dec487f5146078574ec6341ee64703839b8</span>
87+
Change ID: <span class="purple ">nqzqoxtywllzlltmzmyvovqrmolwotzy</span>
88+
Author : <span class="yellow ">Alice</span> &lt;<span class="yellow ">alice@local</span>&gt; (<span class="cyan ">2025-11-06 15:47:11</span>)
89+
Committer: <span class="yellow ">Alice</span> &lt;<span class="yellow ">alice@local</span>&gt; (<span class="cyan ">2025-11-06 15:47:11</span>)
90+
91+
<span class="yellow "> (no description set)</span>
92+
93+
<span class="yellow ">Added regular file tasks_2_and_3.txt:</span>
94+
<span class="green "> 1</span>: <span class="underline "></span><span class="underline green ">Implement task 2</span><span class="green "></span>
95+
<span class="green "> 2</span>: <span class="underline "></span><span class="underline green ">Implement task 3</span><span class="green "></span>
96+
</pre>
97+
98+
As expected, the file for task 1 is not changed in our working copy anymore.
99+
The file for tasks 2 and 3 remain unchanged.
100+
In order to split a single file over multiple commits, we need something more powerful.
101+
102+
## Committing only parts of a file
103+
104+
The command `jj commit` has a flag `--interactive`.
105+
If you use it, Jujutsu will open a "terminal user interface" (TUI).
106+
It takes over your terminal to display a simple, text-based, graphical application.
107+
The way it works it not 100% intuitive for every user, so let's take it slow.
108+
Run the command:
109+
110+
```sh
111+
jj commit --interactive
112+
```
113+
114+
You should see something like this:
115+
116+
![](./scm_record_1.png)
117+
118+
Let check out the menu bar first.
119+
Even though it's in the terminal, you can click on it!
120+
If you click on `[File]`, a drop-down menu with the options `[Confirm]` and `[Quit]` will open.
121+
It also shows the corresponding keyboard shortcuts: <kbd>c</kbd> and <kbd>q</kbd>.
122+
You can explore the other menus yourself, if you like.
123+
124+
The changes in your working copy are below the menu bar.
125+
For now, we can only see the name of the file we changed.
126+
Hit the right arrow to "enter" the file, showing its content.
127+
It should look something like this:
128+
129+
![](./scm_record_2.png)
130+
131+
Indentation indicates a level of hierarchy:
132+
Files are at the top, next are "sections", i.e. consecutive changed lines, and lastly the individual lines.
133+
134+
Now we can select the lines we want to commit first.
135+
In this case, it's the line of task 2.
136+
Navigate to that line with the arrow keys and select it with <kbd>Space</kbd>.
137+
It should look like this:
138+
139+
![](./scm_record_3.png)
140+
141+
Now that we have selected exactly the lines we want to end up in our commit, we can confirm by hitting <kbd>c</kbd> (or clicking on "File > Confirm" in the menu bar).
142+
The TUI will close, and your text editor will open for you to enter a commit message.
143+
Enter "Implement task 2", then save & quit.
144+
You can confirm that the file was correctly split over two commits with `jj show @-` and `jj show`.
145+
146+
Let's tie up the remaining loose ends by committing task 3 and pushing the three new commits to the remote.
147+
148+
```sh
149+
jj commit --message "Implement task 3"
150+
jj bookmark move main --to @-
151+
jj git push
152+
```
153+
154+
##
155+
156+
```admonish success title="You've completed Level 3 ! 🎉"
157+
Now you have the skills to get yourself out of most problems that can come up when working with version control.
158+
Let's summarize what we've learned:
159+
- `jj undo` can restore previous states of your entire repository step-by-step.
160+
Don't worry about making mistakes!
161+
Experiment freely and `jj undo` if anything goes wrong.
162+
- If you want to work on a bookmark that only exists on the remote, for example after making a fresh clone of your repo, run `jj bookmark track`.
163+
- Combining two branches can lead to conflicts if they change the same part of a file.
164+
Resolve such conflicts by carefully removing the conflict markers to produce a sensible result.
165+
- If you end up with commits you no longer need for whatever reason, deleted them with `jj abandon`.
166+
- You can restore the content of a file using `jj restore`.
167+
By default, it restores to the parent of your working copy, but you can specify any commit to restore from with the `--from` flag.
168+
- If you end up with unrelated changes in your working copy, you can put them in separate commits with `jj commit --interactive`.
169+
170+
Now you know pretty much everything you need.
171+
You should be productive and rarely get stuck.
172+
Some readers will decide not to continue further with the tutorial, which is totally fine.
173+
174+
For those who want more, the next level will teach you how to rewrite history effortlessly.
175+
This skill will allow you to produce a much better commit history.
176+
Some projects like the Linux kernel or Jujutsu itself require their contributors to master these skills.
177+
Without them, contributors cannot meet the project's quality standards.
178+
179+
Aside from that, being able to rewrite history is simply freeing.
180+
You'll worry less about how to separate your changes into neat commits and what description to give them, because you can easily change these things later.
181+
182+
Nevertheless, feel free to take a long break before coming back here.
183+
You have learned a lot already, and it will be beneficial to have mastered that with practice before continuing.
184+
185+
At this point, you should also start exploring the Jujutsu CLI a little bit on your own.
186+
This tutorial is not a comprehensive reference of everything Jujutsu has to offer.
187+
Would you like to display all commits made by a specific author?
188+
Run `jj log --help` to find out how.
189+
Would you like to tweak the behavior of Jujutsu in some way?
190+
Maybe the [configuration guide](https://jj-vcs.github.io/jj/latest/config/) can help you out.
191+
```

src/level_3.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ Restore the state (of a specific file) (from a specific commit)
2323
```sh
2424
jj restore [--from <CHANGE_ID>] [FILE_TO_RESTORE]
2525
```
26+
Split a messy working copy
27+
```sh
28+
jj commit --interactive
29+
```
2630
````

src/navigate.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ jj new main
137137
Alright, so Alice now has the latest changes from Bob and can continue to do other work.
138138
She can always come back to her loop experiment later with `jj new`, finish the work and then combine it with the main branch.
139139

140+
##
141+
140142
```admonish success title="You've completed Level 2 ! 🎉"
141143
Now you have the basic skills to collaborate on projects with other people.
142144
Let's summarize what we've learned:

src/reset.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,20 @@ jj commit -m "Remove translations"
287287
jj bookmark move main --to @-
288288
jj git push
289289

290+
if [ "$chapter" = commit_interactive ] ; then success ; fi
291+
292+
# `jj commit --interactive doesn't work in a script, so we reproduce the same
293+
# commits a little differently.
294+
echo "Implement task 1" > task_1.txt
295+
jj commit --message "Implement task 1" task_1.txt
296+
echo "Implement task 2" > tasks_2_and_3.txt
297+
jj commit --message "Implement task 2"
298+
echo "Implement task 3" >> tasks_2_and_3.txt
299+
jj commit --message "Implement task 3"
300+
301+
jj bookmark move main --to @-
302+
jj git push
303+
290304
if [ "$chapter" = complete ] ; then success ; fi
291305

292306
set +x

src/restore.md

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -118,39 +118,3 @@ jj commit -m "Remove translations"
118118
jj bookmark move main --to @-
119119
jj git push
120120
```
121-
122-
```admonish success title="You've completed Level 3 ! 🎉"
123-
Now you have the skills to get yourself out of most problems that can come up when working with version control.
124-
Let's summarize what we've learned:
125-
- `jj undo` can restore previous states of your entire repository step-by-step.
126-
Don't worry about making mistakes!
127-
Experiment freely and `jj undo` if anything goes wrong.
128-
- If you want to work on a bookmark that only exists on the remote, for example after making a fresh clone of your repo, run `jj bookmark track`.
129-
- Combining two branches can lead to conflicts if they change the same part of a file.
130-
Resolve such conflicts by carefully removing the conflict markers to produce a sensible result.
131-
- If you end up with commits you no longer need for whatever reason, deleted them with `jj abandon`.
132-
- You can restore the content of a file using `jj restore`.
133-
By default, it restores to the parent of your working copy, but you can specify any commit to restore from with the `--from` flag.
134-
135-
Now you know pretty much everything you need.
136-
You should be productive and rarely get stuck.
137-
Some readers may decide to stop reading the tutorial here.
138-
139-
For those who want more, the next level will teach you how to rewrite history effortlessly.
140-
This skill will allow you to produce a much better commit history.
141-
Some projects like the Linux kernel or Jujutsu itself require their contributors to know these skills.
142-
Without them, they cannot meet the projects quality standards.
143-
144-
Aside from that, being able to rewrite history is simply freeing.
145-
You'll worry less about how to separate your changes into neat commits and what description to give them, because you can easily change these things later.
146-
147-
Nevertheless, feel free to take a long break before coming back to that.
148-
You have learned a lot so far and it will be beneficial to have mastered that with practice before continuing.
149-
150-
At this point, you should also start to explore the Jujutsu CLI a little bit on your own.
151-
This tutorial is not a comprehensive reference of everything Jujutsu has to offer.
152-
Would you like to display all commits made by a specific author?
153-
Run `jj log --help` to find out how.
154-
Would you like to tweak the behavior of Jujutsu in some way?
155-
Maybe the [configuration guide](https://jj-vcs.github.io/jj/latest/config/) can help you out.
156-
```

src/scm_record_1.png

15.3 KB
Loading

src/scm_record_2.png

31.8 KB
Loading

src/scm_record_3.png

32.8 KB
Loading

0 commit comments

Comments
 (0)