forked from mirrors/jj
revset: add support for glob:pattern
This commit is contained in:
parent
f7c8622981
commit
cfcc76571c
6 changed files with 27 additions and 1 deletions
|
@ -53,6 +53,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
* `jj workspace forget` can now forget multiple workspaces at once.
|
||||
|
||||
* `branches()`/`remote_branches()`/`author()`/`committer()`/`description()`
|
||||
revsets now support glob matching.
|
||||
|
||||
### Fixed bugs
|
||||
|
||||
* Updating the working copy to a commit where a file that's currently ignored
|
||||
|
|
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1051,6 +1051,7 @@ dependencies = [
|
|||
"esl01-renderdag",
|
||||
"futures 0.3.28",
|
||||
"git2",
|
||||
"glob",
|
||||
"hex",
|
||||
"insta",
|
||||
"itertools 0.11.0",
|
||||
|
|
|
@ -145,6 +145,7 @@ Functions that perform string matching support the following pattern syntax.
|
|||
|
||||
* `"string"`, `substring:"string"`: Matches strings that contain `string`.
|
||||
* `exact:"string"`: Matches strings exactly equal to `string`.
|
||||
* `glob:"pattern"`: Matches strings with Unix-style shell wildcard `pattern`.
|
||||
|
||||
## Aliases
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ digest = { workspace = true }
|
|||
futures = { workspace = true }
|
||||
either = { workspace = true }
|
||||
git2 = { workspace = true }
|
||||
glob = { workspace = true }
|
||||
hex = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
maplit = { workspace = true }
|
||||
|
|
|
@ -26,6 +26,9 @@ pub enum StringPatternParseError {
|
|||
/// Unknown pattern kind is specified.
|
||||
#[error(r#"Invalid string pattern kind "{0}""#)]
|
||||
InvalidKind(String),
|
||||
/// Failed to parse glob pattern.
|
||||
#[error(transparent)]
|
||||
GlobPattern(glob::PatternError),
|
||||
}
|
||||
|
||||
/// Pattern to be tested against string property like commit description or
|
||||
|
@ -34,6 +37,8 @@ pub enum StringPatternParseError {
|
|||
pub enum StringPattern {
|
||||
/// Matches strings exactly equal to `string`.
|
||||
Exact(String),
|
||||
/// Unix-style shell wildcard pattern.
|
||||
Glob(glob::Pattern),
|
||||
/// Matches strings that contain `substring`.
|
||||
Substring(String),
|
||||
}
|
||||
|
@ -44,10 +49,20 @@ impl StringPattern {
|
|||
StringPattern::Substring(String::new())
|
||||
}
|
||||
|
||||
/// Parses the given string as glob pattern.
|
||||
pub fn glob(src: &str) -> Result<Self, StringPatternParseError> {
|
||||
// TODO: might be better to do parsing and compilation separately since
|
||||
// not all backends would use the compiled pattern object.
|
||||
// TODO: if no meta character found, it can be mapped to Exact.
|
||||
let pattern = glob::Pattern::new(src).map_err(StringPatternParseError::GlobPattern)?;
|
||||
Ok(StringPattern::Glob(pattern))
|
||||
}
|
||||
|
||||
/// Parses the given string as pattern of the specified `kind`.
|
||||
pub fn from_str_kind(src: &str, kind: &str) -> Result<Self, StringPatternParseError> {
|
||||
match kind {
|
||||
"exact" => Ok(StringPattern::Exact(src.to_owned())),
|
||||
"glob" => StringPattern::glob(src),
|
||||
"substring" => Ok(StringPattern::Substring(src.to_owned())),
|
||||
_ => Err(StringPatternParseError::InvalidKind(kind.to_owned())),
|
||||
}
|
||||
|
@ -59,7 +74,7 @@ impl StringPattern {
|
|||
pub fn as_exact(&self) -> Option<&str> {
|
||||
match self {
|
||||
StringPattern::Exact(literal) => Some(literal),
|
||||
StringPattern::Substring(_) => None,
|
||||
StringPattern::Glob(_) | StringPattern::Substring(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +82,7 @@ impl StringPattern {
|
|||
pub fn matches(&self, haystack: &str) -> bool {
|
||||
match self {
|
||||
StringPattern::Exact(literal) => haystack == literal,
|
||||
StringPattern::Glob(pattern) => pattern.matches(haystack),
|
||||
StringPattern::Substring(needle) => haystack.contains(needle),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1775,6 +1775,10 @@ fn test_evaluate_expression_branches() {
|
|||
resolve_commit_ids(mut_repo, "branches(exact:branch1)"),
|
||||
vec![commit1.id().clone()]
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_commit_ids(mut_repo, r#"branches(glob:"branch?")"#),
|
||||
vec![commit2.id().clone(), commit1.id().clone()]
|
||||
);
|
||||
// Can silently resolve to an empty set if there's no matches
|
||||
assert_eq!(resolve_commit_ids(mut_repo, "branches(branch3)"), vec![]);
|
||||
assert_eq!(
|
||||
|
|
Loading…
Reference in a new issue