mirror of
https://github.com/martinvonz/jj.git
synced 2024-12-25 05:29:39 +00:00
revsets: allow the ..
operator to be used as prefix or suffix (#46)
It makes sense to omit either of the arguments of the `..` operator, even though `..x` is equivalent to `:x`. `x..`, with a implied right argument of `heads()` is more useful.
This commit is contained in:
parent
bc92b82ed4
commit
7d3d0fe83c
3 changed files with 27 additions and 6 deletions
|
@ -68,6 +68,9 @@ only symbols.
|
|||
* `x..y`: Ancestors of `y` that are not also ancestors of `x`, both inclusive.
|
||||
Equivalent to `:y ~ :x`. This is what `git log` calls `x..y` (i.e. the same as
|
||||
we call it).
|
||||
* `..x`: Ancestors of `x`, including the commits in `x` itself. Equivalent to
|
||||
`:x` and provided for consistency.
|
||||
* `x..`: Revisions that are not ancestors of `x`.
|
||||
|
||||
You can use parentheses to control evaluation order, such as `(x & y) | z` or
|
||||
`x & (y | z)`.
|
||||
|
@ -113,7 +116,7 @@ jj log -r @-
|
|||
|
||||
Show commits not on any remote branch:
|
||||
```
|
||||
jj log -r 'remote_branches()..all()'
|
||||
jj log -r 'remote_branches()..'
|
||||
```
|
||||
|
||||
Show all ancestors of the working copy (almost like plain `git log`)
|
||||
|
|
|
@ -52,7 +52,9 @@ neighbors_expression = { primary ~ (parents_op | children_op)* }
|
|||
range_expression = {
|
||||
neighbors_expression ~ dag_range_op ~ neighbors_expression
|
||||
| neighbors_expression ~ range_op ~ neighbors_expression
|
||||
| neighbors_expression ~ range_op
|
||||
| dag_range_op ~ neighbors_expression
|
||||
| range_op ~ neighbors_expression
|
||||
| neighbors_expression ~ dag_range_op
|
||||
| neighbors_expression
|
||||
}
|
||||
|
|
|
@ -406,7 +406,7 @@ fn parse_range_expression_rule(
|
|||
) -> Result<Rc<RevsetExpression>, RevsetParseError> {
|
||||
let first = pairs.next().unwrap();
|
||||
match first.as_rule() {
|
||||
Rule::dag_range_op => {
|
||||
Rule::dag_range_op | Rule::range_op => {
|
||||
return Ok(
|
||||
parse_neighbors_expression_rule(pairs.next().unwrap().into_inner())?.ancestors(),
|
||||
);
|
||||
|
@ -431,9 +431,13 @@ fn parse_range_expression_rule(
|
|||
}
|
||||
}
|
||||
Rule::range_op => {
|
||||
let expression2 =
|
||||
parse_neighbors_expression_rule(pairs.next().unwrap().into_inner())?;
|
||||
expression = expression.range(&expression2);
|
||||
if let Some(heads_pair) = pairs.next() {
|
||||
let heads_expression =
|
||||
parse_neighbors_expression_rule(heads_pair.into_inner())?;
|
||||
expression = expression.range(&heads_expression);
|
||||
} else {
|
||||
expression = expression.range(&RevsetExpression::heads());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
panic!("unxpected revset range operator rule {:?}", next.as_rule());
|
||||
|
@ -1334,6 +1338,13 @@ mod tests {
|
|||
assert_eq!(parse("@:"), Ok(checkout_symbol.descendants()));
|
||||
// Parse the "dag range" operator
|
||||
assert_eq!(parse("foo:bar"), Ok(foo_symbol.dag_range_to(&bar_symbol)));
|
||||
// Parse the "range" prefix operator
|
||||
assert_eq!(parse("..@"), Ok(checkout_symbol.ancestors()));
|
||||
assert_eq!(
|
||||
parse("@.."),
|
||||
Ok(checkout_symbol.range(&RevsetExpression::heads()))
|
||||
);
|
||||
assert_eq!(parse("foo..bar"), Ok(foo_symbol.range(&bar_symbol)));
|
||||
// Parse the "intersection" operator
|
||||
assert_eq!(parse("foo & bar"), Ok(foo_symbol.intersection(&bar_symbol)));
|
||||
// Parse the "union" operator
|
||||
|
@ -1371,13 +1382,18 @@ mod tests {
|
|||
parse("foo+++"),
|
||||
Ok(foo_symbol.children().children().children())
|
||||
);
|
||||
// Parse repeated "ancestors"/"descendants"/"dag range" operators
|
||||
// Parse repeated "ancestors"/"descendants"/"dag range"/"range" operators
|
||||
assert_matches!(parse(":foo:"), Err(RevsetParseError::SyntaxError(_)));
|
||||
assert_matches!(parse("::foo"), Err(RevsetParseError::SyntaxError(_)));
|
||||
assert_matches!(parse("foo::"), Err(RevsetParseError::SyntaxError(_)));
|
||||
assert_matches!(parse("foo::bar"), Err(RevsetParseError::SyntaxError(_)));
|
||||
assert_matches!(parse(":foo:bar"), Err(RevsetParseError::SyntaxError(_)));
|
||||
assert_matches!(parse("foo:bar:"), Err(RevsetParseError::SyntaxError(_)));
|
||||
assert_matches!(parse("....foo"), Err(RevsetParseError::SyntaxError(_)));
|
||||
assert_matches!(parse("foo...."), Err(RevsetParseError::SyntaxError(_)));
|
||||
assert_matches!(parse("foo.....bar"), Err(RevsetParseError::SyntaxError(_)));
|
||||
assert_matches!(parse("..foo..bar"), Err(RevsetParseError::SyntaxError(_)));
|
||||
assert_matches!(parse("foo..bar.."), Err(RevsetParseError::SyntaxError(_)));
|
||||
// Parse combinations of "parents"/"children" operators and the range operators.
|
||||
// The former bind more strongly.
|
||||
assert_eq!(parse("foo-+"), Ok(foo_symbol.parents().children()));
|
||||
|
|
Loading…
Reference in a new issue