op_walk: allow to resolve operation expression from multiple heads

I'll make "op abandon" work without merging op heads.
This commit is contained in:
Yuya Nishihara 2024-07-24 12:09:31 +09:00
parent 4e3a5de6e9
commit 399110b1fc
2 changed files with 15 additions and 6 deletions

View file

@ -57,7 +57,8 @@ pub fn cmd_op_abandon(
return Err(cli_error("--at-op is not respected"));
}
let current_head_op = op_walk::resolve_op_for_load(repo_loader, "@")?;
let resolve_op = |op_str| op_walk::resolve_op_at(op_store, &current_head_op, op_str);
let resolve_op =
|op_str| op_walk::resolve_op_at(op_store, slice::from_ref(&current_head_op), op_str);
let (abandon_root_op, abandon_head_op) =
if let Some((root_op_str, head_op_str)) = args.operation.split_once("..") {
let root_op = if root_op_str.is_empty() {

View file

@ -98,17 +98,25 @@ pub fn resolve_op_with_repo(
repo: &ReadonlyRepo,
op_str: &str,
) -> Result<Operation, OpsetEvaluationError> {
resolve_op_at(repo.op_store(), repo.operation(), op_str)
resolve_op_at(repo.op_store(), slice::from_ref(repo.operation()), op_str)
}
/// Resolves operation set expression at the given head operation.
/// Resolves operation set expression at the given head operations.
pub fn resolve_op_at(
op_store: &Arc<dyn OpStore>,
head_op: &Operation,
head_ops: &[Operation],
op_str: &str,
) -> Result<Operation, OpsetEvaluationError> {
let get_current_op = || Ok(head_op.clone());
let get_head_ops = || Ok(vec![head_op.clone()]);
let get_current_op = || match head_ops {
[head_op] => Ok(head_op.clone()),
[] => Err(OpsetResolutionError::EmptyOperations("@".to_owned()).into()),
_ => Err(OpsetResolutionError::MultipleOperations {
expr: "@".to_owned(),
candidates: head_ops.iter().map(|op| op.id().clone()).collect(),
}
.into()),
};
let get_head_ops = || Ok(head_ops.to_vec());
resolve_single_op(op_store, get_current_op, get_head_ops, op_str)
}