revset.rs
71 lines
| 2.2 KiB
| application/rls-services+xml
|
RustLexer
Simon Sapin
|
r47162 | //! The revset query language | ||
//! | ||||
//! <https://www.mercurial-scm.org/repo/hg/help/revsets> | ||||
Simon Sapin
|
r47459 | use crate::errors::HgError; | ||
Simon Sapin
|
r47162 | use crate::repo::Repo; | ||
use crate::revlog::NodePrefix; | ||||
Pulkit Goyal
|
r47577 | use crate::revlog::{Revision, NULL_REVISION, WORKING_DIRECTORY_HEX}; | ||
Raphaël Gomès
|
r50832 | use crate::revlog::{Revlog, RevlogError}; | ||
Pulkit Goyal
|
r47577 | use crate::Node; | ||
Simon Sapin
|
r47162 | |||
/// Resolve a query string into a single revision. | ||||
/// | ||||
/// Only some of the revset language is implemented yet. | ||||
pub fn resolve_single( | ||||
input: &str, | ||||
repo: &Repo, | ||||
) -> Result<Revision, RevlogError> { | ||||
Simon Sapin
|
r48773 | let changelog = repo.changelog()?; | ||
Simon Sapin
|
r47162 | |||
Raphaël Gomès
|
r48892 | match input { | ||
Raphaël Gomès
|
r48893 | "." => { | ||
let p1 = repo.dirstate_parents()?.p1; | ||||
Raphaël Gomès
|
r50825 | return changelog.revlog.rev_from_node(p1.into()); | ||
Raphaël Gomès
|
r48893 | } | ||
Raphaël Gomès
|
r48892 | "null" => return Ok(NULL_REVISION), | ||
_ => {} | ||||
Simon Sapin
|
r47162 | } | ||
Raphaël Gomès
|
r48892 | match resolve_rev_number_or_hex_prefix(input, &changelog.revlog) { | ||
Err(RevlogError::InvalidRevision) => { | ||||
// TODO: support for the rest of the language here. | ||||
let msg = format!("cannot parse revset '{}'", input); | ||||
Err(HgError::unsupported(msg).into()) | ||||
} | ||||
Raphaël Gomès
|
r50825 | result => result, | ||
Simon Sapin
|
r47162 | } | ||
} | ||||
/// Resolve the small subset of the language suitable for revlogs other than | ||||
/// the changelog, such as in `hg debugdata --manifest` CLI argument. | ||||
/// | ||||
/// * A non-negative decimal integer for a revision number, or | ||||
/// * An hexadecimal string, for the unique node ID that starts with this | ||||
/// prefix | ||||
pub fn resolve_rev_number_or_hex_prefix( | ||||
input: &str, | ||||
revlog: &Revlog, | ||||
) -> Result<Revision, RevlogError> { | ||||
Simon Sapin
|
r48776 | // The Python equivalent of this is part of `revsymbol` in | ||
// `mercurial/scmutil.py` | ||||
Simon Sapin
|
r47162 | if let Ok(integer) = input.parse::<i32>() { | ||
Simon Sapin
|
r48776 | if integer.to_string() == input | ||
&& integer >= 0 | ||||
Raphaël Gomès
|
r51870 | && revlog.has_rev(integer.into()) | ||
Simon Sapin
|
r48776 | { | ||
Raphaël Gomès
|
r51872 | // This is fine because we've just checked that the revision is | ||
// valid for the given revlog. | ||||
return Ok(Revision(integer)); | ||||
Simon Sapin
|
r47162 | } | ||
} | ||||
if let Ok(prefix) = NodePrefix::from_hex(input) { | ||||
Pulkit Goyal
|
r47577 | if prefix.is_prefix_of(&Node::from_hex(WORKING_DIRECTORY_HEX).unwrap()) | ||
{ | ||||
return Err(RevlogError::WDirUnsupported); | ||||
} | ||||
Simon Sapin
|
r48782 | return revlog.rev_from_node(prefix); | ||
Simon Sapin
|
r47162 | } | ||
Err(RevlogError::InvalidRevision) | ||||
} | ||||