From 5612a3106c0905741c2a0fb77f36ee50327b9213 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Fri, 5 May 2023 16:53:27 -0700 Subject: [PATCH] revset: use IdPrefixContext for resolving commit/change ids This is another step towards resolving abbreviated commit ids within a configured revset. --- lib/src/revset.rs | 48 +++++++++++++++++++++++++++++++++++++++-------- src/cli_util.rs | 7 +++++++ 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/lib/src/revset.rs b/lib/src/revset.rs index 397f72044..49d85d449 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -1647,19 +1647,41 @@ impl SymbolResolver for FailingSymbolResolver { } } +pub type PrefixResolver<'a, T> = Box PrefixResolution + 'a>; + /// Resolves the "root" and "@" symbols, branches, remote branches, tags, git /// refs, and full and abbreviated commit and change ids. pub struct DefaultSymbolResolver<'a> { repo: &'a dyn Repo, workspace_id: Option<&'a WorkspaceId>, + commit_id_resolver: Option>, + change_id_resolver: Option>>, } -impl DefaultSymbolResolver<'_> { - pub fn new<'a>( - repo: &'a dyn Repo, - workspace_id: Option<&'a WorkspaceId>, - ) -> DefaultSymbolResolver<'a> { - DefaultSymbolResolver { repo, workspace_id } +impl<'a> DefaultSymbolResolver<'a> { + pub fn new(repo: &'a dyn Repo, workspace_id: Option<&'a WorkspaceId>) -> Self { + DefaultSymbolResolver { + repo, + workspace_id, + commit_id_resolver: None, + change_id_resolver: None, + } + } + + pub fn with_commit_id_resolver( + mut self, + commit_id_resolver: PrefixResolver<'a, CommitId>, + ) -> Self { + self.commit_id_resolver = Some(commit_id_resolver); + self + } + + pub fn with_change_id_resolver( + mut self, + change_id_resolver: PrefixResolver<'a, Vec>, + ) -> Self { + self.change_id_resolver = Some(change_id_resolver); + self } } @@ -1705,7 +1727,12 @@ impl SymbolResolver for DefaultSymbolResolver<'_> { // Try to resolve as a commit id. if let Some(prefix) = HexPrefix::new(symbol) { - match self.repo.index().resolve_prefix(&prefix) { + let prefix_resolution = if let Some(commit_id_resolver) = &self.commit_id_resolver { + commit_id_resolver(&prefix) + } else { + self.repo.index().resolve_prefix(&prefix) + }; + match prefix_resolution { PrefixResolution::AmbiguousMatch => { return Err(RevsetResolutionError::AmbiguousIdPrefix(symbol.to_owned())); } @@ -1720,7 +1747,12 @@ impl SymbolResolver for DefaultSymbolResolver<'_> { // Try to resolve as a change id. if let Some(prefix) = to_forward_hex(symbol).as_deref().and_then(HexPrefix::new) { - match self.repo.resolve_change_id_prefix(&prefix) { + let prefix_resolution = if let Some(change_id_resolver) = &self.change_id_resolver { + change_id_resolver(&prefix) + } else { + self.repo.resolve_change_id_prefix(&prefix) + }; + match prefix_resolution { PrefixResolution::AmbiguousMatch => { return Err(RevsetResolutionError::AmbiguousIdPrefix(symbol.to_owned())); } diff --git a/src/cli_util.rs b/src/cli_util.rs index c99824570..b8cca08e1 100644 --- a/src/cli_util.rs +++ b/src/cli_util.rs @@ -924,7 +924,14 @@ impl WorkspaceCommandHelper { } pub(crate) fn revset_symbol_resolver(&self) -> DefaultSymbolResolver<'_> { + let id_prefix_context = self.id_prefix_context(); + let commit_id_resolver: revset::PrefixResolver<'_, CommitId> = + Box::new(|prefix| id_prefix_context.resolve_commit_prefix(prefix)); + let change_id_resolver: revset::PrefixResolver<'_, Vec> = + Box::new(|prefix| id_prefix_context.resolve_change_prefix(prefix)); DefaultSymbolResolver::new(self.repo().as_ref(), Some(self.workspace_id())) + .with_commit_id_resolver(commit_id_resolver) + .with_change_id_resolver(change_id_resolver) } pub fn id_prefix_context(&self) -> &IdPrefixContext<'_> {