Skip to content

Commit bf9ee74

Browse files
committed
util snapshot: report resulting state
Make jj util snapshot print a small receipt of the resulting state. It now prints the current working-copy state and current operation summary, using existing JJ formatting conventions. When the working-copy commit changes, it also prints the parent commit summaries, matching other working-copy update output. This keeps the command lightweight while making it easier for humans and tools to see what state it left the repo in.
1 parent f849d25 commit bf9ee74

5 files changed

Lines changed: 80 additions & 31 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4141
* Added `jj util backend name` command that prints the backend being used in the
4242
current repo.
4343

44+
* `jj util snapshot` now reports the resulting working-copy state, and prints
45+
the created operation summary if snapshotting created one.
46+
4447
### Fixed bugs
4548

4649
* `jj bookmark forget` no longer prints `Forgot N local bookmarks.` when no

cli/src/commands/util/snapshot.rs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use jj_lib::repo::Repo as _;
16+
1517
use crate::cli_util::CommandHelper;
1618
use crate::command_error::CommandError;
1719
use crate::ui::Ui;
@@ -21,11 +23,12 @@ use crate::ui::Ui;
2123
/// Snapshots the working copy and updates the working-copy commit if the
2224
/// working copy has changed since the last snapshot. Since almost every command
2325
/// snapshots the working copy, there is very little reason to run this command
24-
/// as a human; it is mostly meant for scripts.
26+
/// as a human; it is mostly meant for scripts. It prints the resulting
27+
/// working-copy state together with the current operation summary.
2528
///
26-
/// If you want to see the ID of the current operation after this command, run
29+
/// If you want to query the current operation ID directly, run
2730
/// `jj operation log --limit 1`. However, since that command also snapshots the
28-
/// working copy, there would be no need to run `jj util snapshot` first.
31+
/// working copy, there would often be no need to run `jj util snapshot` first.
2932
#[derive(clap::Args, Clone, Debug)]
3033
pub struct UtilSnapshotArgs {}
3134

@@ -35,14 +38,54 @@ pub async fn cmd_util_snapshot(
3538
_args: &UtilSnapshotArgs,
3639
) -> Result<(), CommandError> {
3740
let mut workspace_command = command.workspace_helper_no_snapshot(ui).await?;
41+
let old_wc_commit_id = workspace_command.get_wc_commit_id().cloned();
3842

3943
// Trigger the snapshot if needed.
40-
let was_snapshot_taken = workspace_command.maybe_snapshot(ui).await?;
41-
if was_snapshot_taken {
42-
writeln!(ui.status(), "Snapshot complete.")?;
44+
let did_operation_change = workspace_command.maybe_snapshot(ui).await?;
45+
let Some(mut formatter) = ui.status_formatter() else {
46+
return Ok(());
47+
};
48+
let status = if did_operation_change {
49+
"Snapshot complete."
4350
} else {
44-
writeln!(ui.status(), "No snapshot needed.")?;
51+
"No snapshot needed."
52+
};
53+
54+
writeln!(formatter, "{status}")?;
55+
56+
if let Some(commit_id) = workspace_command.get_wc_commit_id() {
57+
let commit = workspace_command
58+
.repo()
59+
.store()
60+
.get_commit_async(commit_id)
61+
.await?;
62+
if Some(commit.id()) != old_wc_commit_id.as_ref() {
63+
write!(formatter, "Working copy (@) now at: ")?;
64+
workspace_command
65+
.commit_summary_template()
66+
.format(&commit, formatter.as_mut())?;
67+
writeln!(formatter)?;
68+
for parent in commit.parents().await? {
69+
write!(formatter, "Parent commit (@-) : ")?;
70+
workspace_command
71+
.commit_summary_template()
72+
.format(&parent, formatter.as_mut())?;
73+
writeln!(formatter)?;
74+
}
75+
} else {
76+
write!(formatter, "Working copy change (@): ")?;
77+
workspace_command
78+
.short_change_id_template()
79+
.format(&commit, formatter.as_mut())?;
80+
writeln!(formatter)?;
81+
}
4582
}
4683

84+
write!(formatter, "Current operation: ")?;
85+
workspace_command
86+
.operation_summary_template()
87+
.format(workspace_command.repo().operation(), formatter.as_mut())?;
88+
writeln!(formatter)?;
89+
4790
Ok(())
4891
}

cli/tests/cli-reference@.md.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3550,9 +3550,9 @@ Print the CLI help for all subcommands in Markdown
35503550

35513551
Snapshot the working copy if needed
35523552

3553-
Snapshots the working copy and updates the working-copy commit if the working copy has changed since the last snapshot. Since almost every command snapshots the working copy, there is very little reason to run this command as a human; it is mostly meant for scripts.
3553+
Snapshots the working copy and updates the working-copy commit if the working copy has changed since the last snapshot. Since almost every command snapshots the working copy, there is very little reason to run this command as a human; it is mostly meant for scripts. It prints the resulting working-copy state together with the current operation summary.
35543554

3555-
If you want to see the ID of the current operation after this command, run `jj operation log --limit 1`. However, since that command also snapshots the working copy, there would be no need to run `jj util snapshot` first.
3555+
If you want to query the current operation ID directly, run `jj operation log --limit 1`. However, since that command also snapshots the working copy, there would often be no need to run `jj util snapshot` first.
35563556

35573557
**Usage:** `jj util snapshot`
35583558

cli/tests/test_util_command.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ fn test_util_snapshot() {
289289
insta::assert_snapshot!(output, @"
290290
------- stderr -------
291291
Snapshot complete.
292+
Working copy (@) now at: qpvuntsm 0f7e5910 (no description set)
293+
Parent commit (@-) : zzzzzzzz 00000000 (empty) (no description set)
294+
Current operation: 400986d31c96 (2001-02-03 08:05:08) snapshot working copy
292295
[EOF]
293296
");
294297
}
@@ -303,6 +306,8 @@ fn test_util_snapshot_nothing_changed() {
303306
insta::assert_snapshot!(output, @"
304307
------- stderr -------
305308
No snapshot needed.
309+
Working copy change (@): qpvuntsm
310+
Current operation: 90267f31f904 (2001-02-03 08:05:07) add workspace 'default'
306311
[EOF]
307312
");
308313
}

docs/FAQ.md

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -105,20 +105,20 @@ The wiki lists additional TUIs and GUIs beyond the terminal: [GUI-and-TUI](https
105105
Colocating a Jujutsu repository allows you to use both Jujutsu and Git in the
106106
same working copy. The benefits of doing so are:
107107

108-
- You can use Git commands when you're not sure how to do something with
108+
* You can use Git commands when you're not sure how to do something with
109109
Jujutsu, Jujutsu hasn't yet implemented a feature (e.g., tagging), or you
110110
simply prefer Git in some situations.
111111

112-
- Tooling that expects a Git repository still works (IDEs, build tooling, etc.)
112+
* Tooling that expects a Git repository still works (IDEs, build tooling, etc.)
113113

114114
The [colocation documentation describes the
115115
drawbacks](git-compatibility.md#colocated-jujutsugit-repos) but the most
116116
important ones are:
117117

118-
- Interleaving `git` and `jj` commands may create confusing bookmark conflicts
118+
* Interleaving `git` and `jj` commands may create confusing bookmark conflicts
119119
or divergent changes.
120120

121-
- If the working copy commit or its parent contain any conflicted files, tools
121+
* If the working copy commit or its parent contain any conflicted files, tools
122122
expecting a Git repo may interpret the commit contents or its diff in a wrong
123123
and confusing way. You should avoid doing mutating operations with Git tools
124124
and ignore the confusing information such tools present for conflicted commits
@@ -127,7 +127,7 @@ important ones are:
127127
[\#3979](https://github.com/jj-vcs/jj/issues/3979) for plans to improve
128128
this situation.
129129

130-
- Jujutsu commands may be a little slower in very large repositories due to
130+
* Jujutsu commands may be a little slower in very large repositories due to
131131
importing and exporting changes to Git. Most repositories are not noticeably
132132
affected by this.
133133

@@ -159,7 +159,7 @@ You can also use `jj evolog -r` on revisions that were previously the
159159
working-copy revisions (or on any other revisions). Use `jj evolog -p` as an
160160
easy way to see the evolution of the commit's contents.
161161

162-
### Can I prevent Jujutsu from recording my unfinished work? I'm not ready to commit it.
162+
### Can I prevent Jujutsu from recording my unfinished work? I'm not ready to commit it
163163

164164
Jujutsu automatically records new files in the current working-copy commit and
165165
doesn't provide a way to prevent that.
@@ -282,9 +282,9 @@ $ jj log
282282

283283
Now you're ready to work:
284284

285-
- Your work in progress _xxxxxxxx_ is the first parent of the merge commit.
286-
- The private commit _wwwwwwww_ is the second parent of the merge commit.
287-
- The working copy (_vvvvvvvv_) contains changes from both.
285+
* Your work in progress _xxxxxxxx_ is the first parent of the merge commit.
286+
* The private commit _wwwwwwww_ is the second parent of the merge commit.
287+
* The working copy (_vvvvvvvv_) contains changes from both.
288288

289289
As you work, squash your changes using `jj squash --into xxxxxxxx`.
290290

@@ -459,13 +459,13 @@ Working on feature B
459459
#### Step 3: Move any bookmarks to the original revision
460460

461461
```console
462-
$ jj bookmark move --from 31a347e0 --to b8004ea8
462+
jj bookmark move --from 31a347e0 --to b8004ea8
463463
```
464464

465465
#### Step 4: Abandon the unwanted revision
466466

467467
```console
468-
$ jj abandon 31a347e0
468+
jj abandon 31a347e0
469469
```
470470

471471
Now, we have achieved the exact state we desired:
@@ -571,10 +571,10 @@ commits associated with it.
571571
### I'm experiencing `jj` command issues in a Vite/Vitest project, how do I fix this?
572572

573573
When using Vite or Vitest in a Jujutsu repository, you may experience:
574-
- Very slow vitest startup times
575-
- Timeout errors in `jj` terminal commands
576-
- Errors with 3rd party visual tools like `jjk` or `visual-jj`
577-
- Corrupted `working_copy.lock` files
574+
* Very slow vitest startup times
575+
* Timeout errors in `jj` terminal commands
576+
* Errors with 3rd party visual tools like `jjk` or `visual-jj`
577+
* Corrupted `working_copy.lock` files
578578

579579
This happens because Vite watches the `.jj` directory where Jujutsu stores its internal state.
580580
This creates unnecessary overhead as Vite processes Jujutsu's frequent internal file changes,
@@ -608,13 +608,14 @@ whatever reason, such as for scripting, prompt info, or periodic snapshots in
608608
parallel with something like a
609609
[`watch` command](#can-i-monitor-how-jj-log-evolves), you can run
610610
`jj util snapshot`. By default this command will print whether a snapshot was
611-
taken, which you can silence with the global `--quiet` flag. This command is
611+
taken together with the resulting working-copy state and the current operation
612+
summary. You can silence this with the global `--quiet` flag. This command is
612613
likely most useful for scripting rather than for running on the command line by
613614
a human.
614615

615-
If you want to see the ID of the current operation after this command, it would
616-
be simpler to run `jj operation log --limit 1` directly, since that command also
617-
takes a snapshot if needed.
616+
If you want to query the current operation ID directly, it may be simpler to
617+
run `jj operation log --limit 1`, since that command already takes a snapshot if
618+
needed.
618619

619620
### I want to write a tool which integrates with Jujutsu. Should I use the library or parse the CLI?
620621

@@ -642,12 +643,9 @@ revsets. This seemed unlikely to be accepted by the Git project.
642643

643644
[change]: glossary.md#change
644645
[change ID]: glossary.md#change-id
645-
[colocated]: glossary.md#colocated-workspaces
646646
[commit ID]: glossary.md#commit-id
647-
[commits]: glossary.md#commit
648647
[config]: config.md
649648

650-
[gerrit-integration]: https://gist.github.com/thoughtpolice/8f2fd36ae17cd11b8e7bd93a70e31ad6
651649
[gitignore]: https://git-scm.com/docs/gitignore
652650

653651
[operator]: revsets.md#operators

0 commit comments

Comments
 (0)