Skip to content

Commit 711a396

Browse files
committed
util snapshot: report resulting state
Make jj util snapshot print a small receipt of the resulting state. If the working-copy commit changed, print the normal working-copy summary. Otherwise, print the current working-copy change id. If the command advanced the repo state, also print the current operation summary. 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 711a396

5 files changed

Lines changed: 68 additions & 16 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: 52 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,13 @@ 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, and if the command advanced the repo state it also
28+
/// prints the resulting operation summary.
2529
///
26-
/// If you want to see the ID of the current operation after this command, run
30+
/// If you want to query the current operation ID directly, run
2731
/// `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.
32+
/// working copy, there would often be no need to run `jj util snapshot` first.
2933
#[derive(clap::Args, Clone, Debug)]
3034
pub struct UtilSnapshotArgs {}
3135

@@ -35,13 +39,54 @@ pub async fn cmd_util_snapshot(
3539
_args: &UtilSnapshotArgs,
3640
) -> Result<(), CommandError> {
3741
let mut workspace_command = command.workspace_helper_no_snapshot(ui).await?;
42+
let old_wc_commit_id = workspace_command.get_wc_commit_id().cloned();
3843

3944
// 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.")?;
45+
let did_operation_change = workspace_command.maybe_snapshot(ui).await?;
46+
let current_wc_commit = if let Some(commit_id) = workspace_command.get_wc_commit_id() {
47+
Some(
48+
workspace_command
49+
.repo()
50+
.store()
51+
.get_commit_async(commit_id)
52+
.await?,
53+
)
54+
} else {
55+
None
56+
};
57+
let Some(mut formatter) = ui.status_formatter() else {
58+
return Ok(());
59+
};
60+
let status = if did_operation_change {
61+
"Snapshot complete."
4362
} else {
44-
writeln!(ui.status(), "No snapshot needed.")?;
63+
"No snapshot needed."
64+
};
65+
66+
writeln!(formatter, "{status}")?;
67+
68+
if let Some(commit) = current_wc_commit {
69+
if Some(commit.id()) != old_wc_commit_id.as_ref() {
70+
write!(formatter, "Working copy (@) now at: ")?;
71+
workspace_command
72+
.commit_summary_template()
73+
.format(&commit, formatter.as_mut())?;
74+
writeln!(formatter)?;
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+
}
82+
}
83+
84+
if did_operation_change {
85+
write!(formatter, "Current operation: ")?;
86+
workspace_command
87+
.operation_summary_template()
88+
.format(workspace_command.repo().operation(), formatter.as_mut())?;
89+
writeln!(formatter)?;
4590
}
4691

4792
Ok(())

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, and if the command advanced the repo state it also prints the resulting 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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ 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+
Current operation: 400986d31c96 (2001-02-03 08:05:08) snapshot working copy
292294
[EOF]
293295
");
294296
}
@@ -303,6 +305,7 @@ fn test_util_snapshot_nothing_changed() {
303305
insta::assert_snapshot!(output, @"
304306
------- stderr -------
305307
No snapshot needed.
308+
Working copy change (@): qpvuntsm
306309
[EOF]
307310
");
308311
}

docs/FAQ.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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
612-
likely most useful for scripting rather than for running on the command line by
613-
a human.
614-
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.
611+
taken together with the resulting working-copy state, and if the command
612+
advanced the repo state it will also print the resulting operation summary. You
613+
can silence this with the global `--quiet` flag. This command is likely most
614+
useful for scripting rather than for running on the command line by a human.
615+
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 also 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

0 commit comments

Comments
 (0)