forked from mirrors/jj
revset: homogenize the logic of various symbol resolution steps into a common trait
This commit is contained in:
parent
cf78532bd8
commit
7bdf2b3945
1 changed files with 73 additions and 33 deletions
|
@ -2022,25 +2022,6 @@ pub fn walk_revs<'index>(
|
||||||
.evaluate_programmatic(repo)
|
.evaluate_programmatic(repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_git_ref(repo: &dyn Repo, symbol: &str) -> Option<Vec<CommitId>> {
|
|
||||||
let view = repo.view();
|
|
||||||
for git_ref_prefix in &["", "refs/"] {
|
|
||||||
let target = view.get_git_ref(&(git_ref_prefix.to_string() + symbol));
|
|
||||||
if target.is_present() {
|
|
||||||
return Some(target.added_ids().cloned().collect());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_local_branch(repo: &dyn Repo, symbol: &str) -> Option<Vec<CommitId>> {
|
|
||||||
let view = repo.view();
|
|
||||||
let target = view.get_local_branch(symbol);
|
|
||||||
target
|
|
||||||
.is_present()
|
|
||||||
.then(|| target.added_ids().cloned().collect())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_remote_branch(repo: &dyn Repo, name: &str, remote: &str) -> Option<Vec<CommitId>> {
|
fn resolve_remote_branch(repo: &dyn Repo, name: &str, remote: &str) -> Option<Vec<CommitId>> {
|
||||||
let view = repo.view();
|
let view = repo.view();
|
||||||
let target = match (name, remote) {
|
let target = match (name, remote) {
|
||||||
|
@ -2103,6 +2084,70 @@ impl SymbolResolver for FailingSymbolResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A symbol resolver for a specific namespace of labels.
|
||||||
|
///
|
||||||
|
/// Returns None if it cannot handle the symbol.
|
||||||
|
pub trait PartialSymbolResolver {
|
||||||
|
fn resolve_symbol(
|
||||||
|
&self,
|
||||||
|
repo: &dyn Repo,
|
||||||
|
symbol: &str,
|
||||||
|
) -> Result<Option<Vec<CommitId>>, RevsetResolutionError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TagResolver;
|
||||||
|
|
||||||
|
impl PartialSymbolResolver for TagResolver {
|
||||||
|
fn resolve_symbol(
|
||||||
|
&self,
|
||||||
|
repo: &dyn Repo,
|
||||||
|
symbol: &str,
|
||||||
|
) -> Result<Option<Vec<CommitId>>, RevsetResolutionError> {
|
||||||
|
let target = repo.view().get_tag(symbol);
|
||||||
|
Ok(target
|
||||||
|
.is_present()
|
||||||
|
.then(|| target.added_ids().cloned().collect()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BranchResolver;
|
||||||
|
|
||||||
|
impl PartialSymbolResolver for BranchResolver {
|
||||||
|
fn resolve_symbol(
|
||||||
|
&self,
|
||||||
|
repo: &dyn Repo,
|
||||||
|
symbol: &str,
|
||||||
|
) -> Result<Option<Vec<CommitId>>, RevsetResolutionError> {
|
||||||
|
let target = repo.view().get_local_branch(symbol);
|
||||||
|
Ok(target
|
||||||
|
.is_present()
|
||||||
|
.then(|| target.added_ids().cloned().collect()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GitRefResolver;
|
||||||
|
|
||||||
|
impl PartialSymbolResolver for GitRefResolver {
|
||||||
|
fn resolve_symbol(
|
||||||
|
&self,
|
||||||
|
repo: &dyn Repo,
|
||||||
|
symbol: &str,
|
||||||
|
) -> Result<Option<Vec<CommitId>>, RevsetResolutionError> {
|
||||||
|
let view = repo.view();
|
||||||
|
for git_ref_prefix in &["", "refs/"] {
|
||||||
|
let target = view.get_git_ref(&(git_ref_prefix.to_string() + symbol));
|
||||||
|
if target.is_present() {
|
||||||
|
return Ok(Some(target.added_ids().cloned().collect()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEFAULT_RESOLVERS: &[&'static dyn PartialSymbolResolver] =
|
||||||
|
&[&TagResolver, &BranchResolver, &GitRefResolver];
|
||||||
|
|
||||||
pub type PrefixResolver<'a, T> = Box<dyn Fn(&dyn Repo, &HexPrefix) -> PrefixResolution<T> + 'a>;
|
pub type PrefixResolver<'a, T> = Box<dyn Fn(&dyn Repo, &HexPrefix) -> PrefixResolution<T> + 'a>;
|
||||||
|
|
||||||
/// Resolves branches, remote branches, tags, git refs, and full and abbreviated
|
/// Resolves branches, remote branches, tags, git refs, and full and abbreviated
|
||||||
|
@ -2139,6 +2184,10 @@ impl<'a> DefaultSymbolResolver<'a> {
|
||||||
self.change_id_resolver = change_id_resolver;
|
self.change_id_resolver = change_id_resolver;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn partial_resolvers(&self) -> impl Iterator<Item = &dyn PartialSymbolResolver> {
|
||||||
|
DEFAULT_RESOLVERS.iter().copied()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SymbolResolver for DefaultSymbolResolver<'_> {
|
impl SymbolResolver for DefaultSymbolResolver<'_> {
|
||||||
|
@ -2147,21 +2196,12 @@ impl SymbolResolver for DefaultSymbolResolver<'_> {
|
||||||
return Err(RevsetResolutionError::EmptyString);
|
return Err(RevsetResolutionError::EmptyString);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to resolve as a tag
|
for partial_resolver in self.partial_resolvers() {
|
||||||
let target = self.repo.view().get_tag(symbol);
|
if let Some(ids) = partial_resolver.resolve_symbol(self.repo, symbol)? {
|
||||||
if target.is_present() {
|
return Ok(ids);
|
||||||
return Ok(target.added_ids().cloned().collect());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Try to resolve as a branch
|
|
||||||
if let Some(ids) = resolve_local_branch(self.repo, symbol) {
|
|
||||||
return Ok(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to resolve as a git ref
|
|
||||||
if let Some(ids) = resolve_git_ref(self.repo, symbol) {
|
|
||||||
return Ok(ids);
|
|
||||||
}
|
}
|
||||||
|
// TODO: Convert prefix resolvers
|
||||||
|
|
||||||
// Try to resolve as a commit id.
|
// Try to resolve as a commit id.
|
||||||
if let Some(prefix) = HexPrefix::new(symbol) {
|
if let Some(prefix) = HexPrefix::new(symbol) {
|
||||||
|
|
Loading…
Reference in a new issue