cli: plumbing to make SnapshotStats available to cmd_status

This commit is contained in:
Christian Stoitner 2024-12-17 20:50:27 +01:00
parent cb28685901
commit 3aa97099d6
2 changed files with 50 additions and 32 deletions

View file

@ -385,10 +385,20 @@ impl CommandHelper {
/// Loads workspace and repo, then snapshots the working copy if allowed. /// Loads workspace and repo, then snapshots the working copy if allowed.
#[instrument(skip(self, ui))] #[instrument(skip(self, ui))]
pub fn workspace_helper(&self, ui: &Ui) -> Result<WorkspaceCommandHelper, CommandError> { pub fn workspace_helper(&self, ui: &Ui) -> Result<WorkspaceCommandHelper, CommandError> {
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 mut workspace_command = self.workspace_helper_no_snapshot(ui)?;
let workspace_command = match workspace_command.maybe_snapshot_impl(ui) { let (workspace_command, stats) = match workspace_command.maybe_snapshot_impl(ui) {
Ok(()) => workspace_command, Ok(stats) => (workspace_command, stats),
Err(SnapshotWorkingCopyError::Command(err)) => return Err(err), Err(SnapshotWorkingCopyError::Command(err)) => return Err(err),
Err(SnapshotWorkingCopyError::StaleWorkingCopy(err)) => { Err(SnapshotWorkingCopyError::StaleWorkingCopy(err)) => {
let auto_update_stale = self.settings().get_bool("snapshot.auto-update-stale")?; 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 /// Loads workspace and repo, but never snapshots the working copy. Most
@ -452,7 +462,7 @@ impl CommandHelper {
pub fn recover_stale_working_copy( pub fn recover_stale_working_copy(
&self, &self,
ui: &Ui, ui: &Ui,
) -> Result<WorkspaceCommandHelper, CommandError> { ) -> Result<(WorkspaceCommandHelper, SnapshotStats), CommandError> {
let workspace = self.load_workspace()?; let workspace = self.load_workspace()?;
let op_id = workspace.working_copy().operation_id(); 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 // 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 // merged repo wouldn't change because the old one wins, but it's probably
// fine if we picked the new wc_commit_id. // 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 wc_commit_id = workspace_command.get_wc_commit_id().unwrap();
let repo = workspace_command.repo().clone(); let repo = workspace_command.repo().clone();
@ -516,7 +526,7 @@ impl CommandHelper {
} }
}; };
Ok(workspace_command) Ok((workspace_command, stats))
} }
Err(e @ OpStoreError::ObjectNotFound { .. }) => { Err(e @ OpStoreError::ObjectNotFound { .. }) => {
writeln!( writeln!(
@ -526,8 +536,8 @@ impl CommandHelper {
)?; )?;
let mut workspace_command = self.workspace_helper_no_snapshot(ui)?; let mut workspace_command = self.workspace_helper_no_snapshot(ui)?;
workspace_command.create_and_check_out_recovery_commit(ui)?; let stats = workspace_command.create_and_check_out_recovery_commit(ui)?;
Ok(workspace_command) Ok((workspace_command, stats))
} }
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
@ -1014,29 +1024,31 @@ impl WorkspaceCommandHelper {
} }
#[instrument(skip_all)] #[instrument(skip_all)]
fn maybe_snapshot_impl(&mut self, ui: &Ui) -> Result<(), SnapshotWorkingCopyError> { fn maybe_snapshot_impl(&mut self, ui: &Ui) -> Result<SnapshotStats, SnapshotWorkingCopyError> {
if self.may_update_working_copy { if !self.may_update_working_copy {
if self.working_copy_shared_with_git { return Ok(SnapshotStats::default());
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)?;
}
} }
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 /// Snapshot the working copy if allowed, and import Git refs if the working
/// copy is collocated with Git. /// copy is collocated with Git.
#[instrument(skip_all)] #[instrument(skip_all)]
pub fn maybe_snapshot(&mut self, ui: &Ui) -> Result<(), CommandError> { pub fn maybe_snapshot(&mut self, ui: &Ui) -> Result<SnapshotStats, CommandError> {
self.maybe_snapshot_impl(ui) self.maybe_snapshot_impl(ui)
.map_err(|err| err.into_command_error()) .map_err(|err| err.into_command_error())
} }
@ -1186,7 +1198,10 @@ impl WorkspaceCommandHelper {
Ok((locked_ws, wc_commit)) 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<SnapshotStats, CommandError> {
self.check_working_copy_writable()?; self.check_working_copy_writable()?;
let workspace_id = self.workspace_id().clone(); let workspace_id = self.workspace_id().clone();
@ -1756,7 +1771,10 @@ to the current parents may contain changes from multiple commits.
} }
#[instrument(skip_all)] #[instrument(skip_all)]
fn snapshot_working_copy(&mut self, ui: &Ui) -> Result<(), SnapshotWorkingCopyError> { fn snapshot_working_copy(
&mut self,
ui: &Ui,
) -> Result<SnapshotStats, SnapshotWorkingCopyError> {
let workspace_id = self.workspace_id().to_owned(); let workspace_id = self.workspace_id().to_owned();
let get_wc_commit = |repo: &ReadonlyRepo| -> Result<Option<_>, _> { let get_wc_commit = |repo: &ReadonlyRepo| -> Result<Option<_>, _> {
repo.view() 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 { 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 // If the workspace has been deleted, it's unclear what to do, so we just skip
// committing the working copy. // committing the working copy.
return Ok(()); return Ok(SnapshotStats::default());
}; };
let auto_tracking_matcher = self let auto_tracking_matcher = self
.auto_tracking_matcher(ui) .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)? { let wc_commit = if let Some(wc_commit) = get_wc_commit(&repo)? {
wc_commit wc_commit
} else { } else {
return Ok(()); // The workspace has been deleted (see // The workspace has been deleted (see above)
// above) return Ok(SnapshotStats::default());
}; };
(repo, wc_commit) (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)?; .map_err(snapshot_command_error)?;
print_snapshot_stats(ui, &stats, &self.env.path_converter) print_snapshot_stats(ui, &stats, &self.env.path_converter)
.map_err(snapshot_command_error)?; .map_err(snapshot_command_error)?;
Ok(()) Ok(stats)
} }
fn update_working_copy( fn update_working_copy(

View file

@ -47,7 +47,7 @@ pub(crate) fn cmd_status(
command: &CommandHelper, command: &CommandHelper,
args: &StatusArgs, args: &StatusArgs,
) -> Result<(), CommandError> { ) -> 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 repo = workspace_command.repo();
let maybe_wc_commit = workspace_command let maybe_wc_commit = workspace_command
.get_wc_commit_id() .get_wc_commit_id()