diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index d52c1b5b93..ff8e4f3042 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -659,11 +659,8 @@ impl CommandHelper { }, ) } else { - let operation = op_walk::resolve_op_for_load( - repo_loader.op_store(), - repo_loader.op_heads_store(), - &self.global_args.at_operation, - )?; + let operation = + op_walk::resolve_op_for_load(repo_loader, &self.global_args.at_operation)?; Ok(operation) } } @@ -975,14 +972,7 @@ impl WorkspaceCommandHelper { } pub fn resolve_single_op(&self, op_str: &str) -> Result { - // When resolving the "@" operation in a `ReadonlyRepo`, we resolve it to the - // operation the repo was loaded at. - op_walk::resolve_single_op( - self.repo().op_store(), - self.repo().op_heads_store(), - || Ok(self.repo().operation().clone()), - op_str, - ) + op_walk::resolve_op_with_repo(self.repo(), op_str) } /// Resolve a revset to a single revision. Return an error if the revset is diff --git a/cli/src/commands/debug.rs b/cli/src/commands/debug.rs index c2fa02b7f3..548f33cf0c 100644 --- a/cli/src/commands/debug.rs +++ b/cli/src/commands/debug.rs @@ -267,11 +267,7 @@ fn cmd_debug_operation( // even if e.g. the view object is broken. let workspace = command.load_workspace()?; let repo_loader = workspace.repo_loader(); - let op = op_walk::resolve_op_for_load( - repo_loader.op_store(), - repo_loader.op_heads_store(), - &args.operation, - )?; + let op = op_walk::resolve_op_for_load(repo_loader, &args.operation)?; if args.display == DebugOperationDisplay::Id { writeln!(ui.stdout(), "{}", op.id().hex())?; return Ok(()); diff --git a/lib/src/op_walk.rs b/lib/src/op_walk.rs index 09a393ab65..4b02a17373 100644 --- a/lib/src/op_walk.rs +++ b/lib/src/op_walk.rs @@ -25,6 +25,7 @@ use crate::backend::ObjectId as _; use crate::op_heads_store::{OpHeadResolutionError, OpHeadsStore}; use crate::op_store::{OpStore, OpStoreError, OpStoreResult, OperationId}; use crate::operation::Operation; +use crate::repo::{ReadonlyRepo, Repo as _, RepoLoader}; use crate::{dag_walk, op_heads_store}; /// Error that may occur during evaluation of operation set expression. @@ -66,23 +67,37 @@ pub enum OpsetResolutionError { /// Resolves operation set expression without loading a repo. pub fn resolve_op_for_load( - op_store: &Arc, - op_heads_store: &Arc, + repo_loader: &RepoLoader, op_str: &str, ) -> Result { + let op_store = repo_loader.op_store(); + let op_heads_store = repo_loader.op_heads_store().as_ref(); let get_current_op = || { - op_heads_store::resolve_op_heads(op_heads_store.as_ref(), op_store, |_| { + op_heads_store::resolve_op_heads(op_heads_store, op_store, |_| { Err(OpsetResolutionError::MultipleOperations("@".to_owned()).into()) }) }; resolve_single_op(op_store, op_heads_store, get_current_op, op_str) } +/// Resolves operation set expression against the loaded repo. +/// +/// The "@" symbol will be resolved to the operation the repo was loaded at. +pub fn resolve_op_with_repo( + repo: &ReadonlyRepo, + op_str: &str, +) -> Result { + let op_store = repo.op_store(); + let op_heads_store = repo.op_heads_store().as_ref(); + let get_current_op = || Ok(repo.operation().clone()); + resolve_single_op(op_store, op_heads_store, get_current_op, op_str) +} + /// Resolves operation set expression with the given "@" symbol resolution /// callback. -pub fn resolve_single_op( +fn resolve_single_op( op_store: &Arc, - op_heads_store: &Arc, + op_heads_store: &dyn OpHeadsStore, get_current_op: impl FnOnce() -> Result, op_str: &str, ) -> Result { @@ -108,7 +123,7 @@ pub fn resolve_single_op( fn resolve_single_op_from_store( op_store: &Arc, - op_heads_store: &Arc, + op_heads_store: &dyn OpHeadsStore, op_str: &str, ) -> Result { if op_str.is_empty() || !op_str.as_bytes().iter().all(|b| b.is_ascii_hexdigit()) { @@ -145,7 +160,7 @@ fn resolve_single_op_from_store( fn find_all_operations( op_store: &Arc, - op_heads_store: &Arc, + op_heads_store: &dyn OpHeadsStore, ) -> Result, OpStoreError> { let mut visited = HashSet::new(); let mut work: VecDeque<_> = op_heads_store.get_op_heads().into_iter().collect();