diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index 97ab3985b..a4e56ed2f 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -385,10 +385,20 @@ impl CommandHelper { /// Loads workspace and repo, then snapshots the working copy if allowed. #[instrument(skip(self, ui))] pub fn workspace_helper(&self, ui: &Ui) -> Result { + Ok(self.workspace_helper_with_stats(ui)?.0) + } + + /// Loads workspace and repo, then snapshots the working copy if allowed and + /// returns the SnapshotStats. + #[instrument(skip(self, ui))] + pub fn workspace_helper_with_stats( + &self, + ui: &Ui, + ) -> Result<(WorkspaceCommandHelper, SnapshotStats), CommandError> { let mut workspace_command = self.workspace_helper_no_snapshot(ui)?; - let workspace_command = match workspace_command.maybe_snapshot_impl(ui) { - Ok(()) => workspace_command, + let (workspace_command, stats) = match workspace_command.maybe_snapshot_impl(ui) { + Ok(stats) => (workspace_command, stats), Err(SnapshotWorkingCopyError::Command(err)) => return Err(err), Err(SnapshotWorkingCopyError::StaleWorkingCopy(err)) => { let auto_update_stale = self.settings().get_bool("snapshot.auto-update-stale")?; @@ -404,7 +414,7 @@ impl CommandHelper { } }; - Ok(workspace_command) + Ok((workspace_command, stats)) } /// Loads workspace and repo, but never snapshots the working copy. Most @@ -452,7 +462,7 @@ impl CommandHelper { pub fn recover_stale_working_copy( &self, ui: &Ui, - ) -> Result { + ) -> Result<(WorkspaceCommandHelper, SnapshotStats), CommandError> { let workspace = self.load_workspace()?; let op_id = workspace.working_copy().operation_id(); @@ -465,7 +475,7 @@ impl CommandHelper { // operation, then merge the divergent operations. The wc_commit_id of the // merged repo wouldn't change because the old one wins, but it's probably // fine if we picked the new wc_commit_id. - workspace_command.maybe_snapshot(ui)?; + let stats = workspace_command.maybe_snapshot(ui)?; let wc_commit_id = workspace_command.get_wc_commit_id().unwrap(); let repo = workspace_command.repo().clone(); @@ -516,7 +526,7 @@ impl CommandHelper { } }; - Ok(workspace_command) + Ok((workspace_command, stats)) } Err(e @ OpStoreError::ObjectNotFound { .. }) => { writeln!( @@ -526,8 +536,8 @@ impl CommandHelper { )?; let mut workspace_command = self.workspace_helper_no_snapshot(ui)?; - workspace_command.create_and_check_out_recovery_commit(ui)?; - Ok(workspace_command) + let stats = workspace_command.create_and_check_out_recovery_commit(ui)?; + Ok((workspace_command, stats)) } Err(e) => Err(e.into()), } @@ -1014,29 +1024,31 @@ impl WorkspaceCommandHelper { } #[instrument(skip_all)] - fn maybe_snapshot_impl(&mut self, ui: &Ui) -> Result<(), SnapshotWorkingCopyError> { - if self.may_update_working_copy { - if self.working_copy_shared_with_git { - self.import_git_head(ui).map_err(snapshot_command_error)?; - } - // Because the Git refs (except HEAD) aren't imported yet, the ref - // pointing to the new working-copy commit might not be exported. - // In that situation, the ref would be conflicted anyway, so export - // failure is okay. - self.snapshot_working_copy(ui)?; - - // import_git_refs() can rebase the working-copy commit. - if self.working_copy_shared_with_git { - self.import_git_refs(ui).map_err(snapshot_command_error)?; - } + fn maybe_snapshot_impl(&mut self, ui: &Ui) -> Result { + if !self.may_update_working_copy { + return Ok(SnapshotStats::default()); } - Ok(()) + + if self.working_copy_shared_with_git { + self.import_git_head(ui).map_err(snapshot_command_error)?; + } + // Because the Git refs (except HEAD) aren't imported yet, the ref + // pointing to the new working-copy commit might not be exported. + // In that situation, the ref would be conflicted anyway, so export + // failure is okay. + let stats = self.snapshot_working_copy(ui)?; + + // import_git_refs() can rebase the working-copy commit. + if self.working_copy_shared_with_git { + self.import_git_refs(ui).map_err(snapshot_command_error)?; + } + Ok(stats) } /// Snapshot the working copy if allowed, and import Git refs if the working /// copy is collocated with Git. #[instrument(skip_all)] - pub fn maybe_snapshot(&mut self, ui: &Ui) -> Result<(), CommandError> { + pub fn maybe_snapshot(&mut self, ui: &Ui) -> Result { self.maybe_snapshot_impl(ui) .map_err(|err| err.into_command_error()) } @@ -1186,7 +1198,10 @@ impl WorkspaceCommandHelper { Ok((locked_ws, wc_commit)) } - fn create_and_check_out_recovery_commit(&mut self, ui: &Ui) -> Result<(), CommandError> { + fn create_and_check_out_recovery_commit( + &mut self, + ui: &Ui, + ) -> Result { self.check_working_copy_writable()?; let workspace_id = self.workspace_id().clone(); @@ -1756,7 +1771,10 @@ to the current parents may contain changes from multiple commits. } #[instrument(skip_all)] - fn snapshot_working_copy(&mut self, ui: &Ui) -> Result<(), SnapshotWorkingCopyError> { + fn snapshot_working_copy( + &mut self, + ui: &Ui, + ) -> Result { let workspace_id = self.workspace_id().to_owned(); let get_wc_commit = |repo: &ReadonlyRepo| -> Result, _> { repo.view() @@ -1769,7 +1787,7 @@ to the current parents may contain changes from multiple commits. let Some(wc_commit) = get_wc_commit(&repo)? else { // If the workspace has been deleted, it's unclear what to do, so we just skip // committing the working copy. - return Ok(()); + return Ok(SnapshotStats::default()); }; let auto_tracking_matcher = self .auto_tracking_matcher(ui) @@ -1795,8 +1813,8 @@ to the current parents may contain changes from multiple commits. let wc_commit = if let Some(wc_commit) = get_wc_commit(&repo)? { wc_commit } else { - return Ok(()); // The workspace has been deleted (see - // above) + // The workspace has been deleted (see above) + return Ok(SnapshotStats::default()); }; (repo, wc_commit) } @@ -1886,7 +1904,7 @@ See https://jj-vcs.github.io/jj/latest/working-copy/#stale-working-copy \ .map_err(snapshot_command_error)?; print_snapshot_stats(ui, &stats, &self.env.path_converter) .map_err(snapshot_command_error)?; - Ok(()) + Ok(stats) } fn update_working_copy( diff --git a/cli/src/commands/status.rs b/cli/src/commands/status.rs index bf91c26ab..a0e857384 100644 --- a/cli/src/commands/status.rs +++ b/cli/src/commands/status.rs @@ -47,7 +47,7 @@ pub(crate) fn cmd_status( command: &CommandHelper, args: &StatusArgs, ) -> Result<(), CommandError> { - let workspace_command = command.workspace_helper(ui)?; + let (workspace_command, _snapshot_stats) = command.workspace_helper_with_stats(ui)?; let repo = workspace_command.repo(); let maybe_wc_commit = workspace_command .get_wc_commit_id()