ok/jj
1
0
Fork 0
forked from mirrors/jj

revset: add generation parameter to RevsetExpression::Ancestors/Range

Parents(heads) will be translated to Ancestors(heads, 1..2).
This commit is contained in:
Yuya Nishihara 2022-12-09 22:45:11 +09:00
parent 29a565e3fb
commit 46b1465324

View file

@ -318,6 +318,9 @@ impl error::Error for RevsetParseError {
} }
} }
// assumes index has less than u32::MAX entries.
const GENERATION_RANGE_FULL: Range<u32> = 0..u32::MAX;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub enum RevsetFilterPredicate { pub enum RevsetFilterPredicate {
/// Commits with number of parents in the range. /// Commits with number of parents in the range.
@ -340,11 +343,15 @@ pub enum RevsetExpression {
Symbol(String), Symbol(String),
Parents(Rc<RevsetExpression>), Parents(Rc<RevsetExpression>),
Children(Rc<RevsetExpression>), Children(Rc<RevsetExpression>),
Ancestors(Rc<RevsetExpression>), Ancestors {
heads: Rc<RevsetExpression>,
generation: Range<u32>,
},
// Commits that are ancestors of "heads" but not ancestors of "roots" // Commits that are ancestors of "heads" but not ancestors of "roots"
Range { Range {
roots: Rc<RevsetExpression>, roots: Rc<RevsetExpression>,
heads: Rc<RevsetExpression>, heads: Rc<RevsetExpression>,
generation: Range<u32>,
}, },
// Commits that are descendants of "roots" and ancestors of "heads" // Commits that are descendants of "roots" and ancestors of "heads"
DagRange { DagRange {
@ -440,7 +447,10 @@ impl RevsetExpression {
/// Ancestors of `self`, including `self`. /// Ancestors of `self`, including `self`.
pub fn ancestors(self: &Rc<RevsetExpression>) -> Rc<RevsetExpression> { pub fn ancestors(self: &Rc<RevsetExpression>) -> Rc<RevsetExpression> {
Rc::new(RevsetExpression::Ancestors(self.clone())) Rc::new(RevsetExpression::Ancestors {
heads: self.clone(),
generation: GENERATION_RANGE_FULL,
})
} }
/// Children of `self`. /// Children of `self`.
@ -479,6 +489,7 @@ impl RevsetExpression {
Rc::new(RevsetExpression::Range { Rc::new(RevsetExpression::Range {
roots: self.clone(), roots: self.clone(),
heads: heads.clone(), heads: heads.clone(),
generation: GENERATION_RANGE_FULL,
}) })
} }
@ -1077,11 +1088,23 @@ fn transform_expression_bottom_up(
RevsetExpression::Children(roots) => { RevsetExpression::Children(roots) => {
transform_rec(roots, f).map(RevsetExpression::Children) transform_rec(roots, f).map(RevsetExpression::Children)
} }
RevsetExpression::Ancestors(base) => { RevsetExpression::Ancestors { heads, generation } => {
transform_rec(base, f).map(RevsetExpression::Ancestors) transform_rec(heads, f).map(|heads| RevsetExpression::Ancestors {
heads,
generation: generation.clone(),
})
} }
RevsetExpression::Range { roots, heads } => transform_rec_pair((roots, heads), f) RevsetExpression::Range {
.map(|(roots, heads)| RevsetExpression::Range { roots, heads }), roots,
heads,
generation,
} => transform_rec_pair((roots, heads), f).map(|(roots, heads)| {
RevsetExpression::Range {
roots,
heads,
generation: generation.clone(),
}
}),
RevsetExpression::DagRange { roots, heads } => transform_rec_pair((roots, heads), f) RevsetExpression::DagRange { roots, heads } => transform_rec_pair((roots, heads), f)
.map(|(roots, heads)| RevsetExpression::DagRange { roots, heads }), .map(|(roots, heads)| RevsetExpression::DagRange { roots, heads }),
RevsetExpression::VisibleHeads => None, RevsetExpression::VisibleHeads => None,
@ -1268,12 +1291,17 @@ fn fold_difference(expression: &Rc<RevsetExpression>) -> Option<Rc<RevsetExpress
) -> Rc<RevsetExpression> { ) -> Rc<RevsetExpression> {
match (expression.as_ref(), complement.as_ref()) { match (expression.as_ref(), complement.as_ref()) {
// :heads & ~(:roots) -> roots..heads // :heads & ~(:roots) -> roots..heads
(RevsetExpression::Ancestors(heads), RevsetExpression::Ancestors(roots)) => { (
Rc::new(RevsetExpression::Range { RevsetExpression::Ancestors { heads, generation },
roots: roots.clone(), RevsetExpression::Ancestors {
heads: heads.clone(), heads: roots,
}) generation: GENERATION_RANGE_FULL,
} },
) => Rc::new(RevsetExpression::Range {
roots: roots.clone(),
heads: heads.clone(),
generation: generation.clone(),
}),
_ => expression.minus(complement), _ => expression.minus(complement),
} }
} }
@ -1301,8 +1329,16 @@ fn fold_difference(expression: &Rc<RevsetExpression>) -> Option<Rc<RevsetExpress
fn unfold_difference(expression: &Rc<RevsetExpression>) -> Option<Rc<RevsetExpression>> { fn unfold_difference(expression: &Rc<RevsetExpression>) -> Option<Rc<RevsetExpression>> {
transform_expression_bottom_up(expression, |expression| match expression.as_ref() { transform_expression_bottom_up(expression, |expression| match expression.as_ref() {
// roots..heads -> :heads & ~(:roots) // roots..heads -> :heads & ~(:roots)
RevsetExpression::Range { roots, heads } => { RevsetExpression::Range {
Some(heads.ancestors().intersection(&roots.ancestors().negated())) roots,
heads,
generation,
} => {
let heads_ancestors = Rc::new(RevsetExpression::Ancestors {
heads: heads.clone(),
generation: generation.clone(),
});
Some(heads_ancestors.intersection(&roots.ancestors().negated()))
} }
RevsetExpression::Difference(expression1, expression2) => { RevsetExpression::Difference(expression1, expression2) => {
Some(expression1.intersection(&expression2.negated())) Some(expression1.intersection(&expression2.negated()))
@ -1762,16 +1798,30 @@ pub fn evaluate_expression<'repo>(
candidate_set, candidate_set,
})) }))
} }
RevsetExpression::Ancestors(base_expression) => RevsetExpression::none() RevsetExpression::Ancestors { heads, generation } => {
.range(base_expression) let range_expression = RevsetExpression::Range {
.evaluate(repo, workspace_ctx), roots: RevsetExpression::none(),
RevsetExpression::Range { roots, heads } => { heads: heads.clone(),
generation: generation.clone(),
};
range_expression.evaluate(repo, workspace_ctx)
}
RevsetExpression::Range {
roots,
heads,
generation,
} => {
let root_set = roots.evaluate(repo, workspace_ctx)?; let root_set = roots.evaluate(repo, workspace_ctx)?;
let root_ids = root_set.iter().commit_ids().collect_vec(); let root_ids = root_set.iter().commit_ids().collect_vec();
let head_set = heads.evaluate(repo, workspace_ctx)?; let head_set = heads.evaluate(repo, workspace_ctx)?;
let head_ids = head_set.iter().commit_ids().collect_vec(); let head_ids = head_set.iter().commit_ids().collect_vec();
let walk = repo.index().walk_revs(&head_ids, &root_ids); let walk = repo.index().walk_revs(&head_ids, &root_ids);
Ok(Box::new(RevWalkRevset { walk })) if generation == &GENERATION_RANGE_FULL {
Ok(Box::new(RevWalkRevset { walk }))
} else {
let walk = walk.filter_by_generation(generation.clone());
Ok(Box::new(RevWalkRevset { walk }))
}
} }
// Clippy doesn't seem to understand that we collect the iterator in order to iterate in // Clippy doesn't seem to understand that we collect the iterator in order to iterate in
// reverse // reverse
@ -2067,7 +2117,10 @@ mod tests {
); );
assert_eq!( assert_eq!(
wc_symbol.ancestors(), wc_symbol.ancestors(),
Rc::new(RevsetExpression::Ancestors(wc_symbol.clone())) Rc::new(RevsetExpression::Ancestors {
heads: wc_symbol.clone(),
generation: GENERATION_RANGE_FULL,
})
); );
assert_eq!( assert_eq!(
foo_symbol.children(), foo_symbol.children(),
@ -2098,7 +2151,8 @@ mod tests {
foo_symbol.range(&wc_symbol), foo_symbol.range(&wc_symbol),
Rc::new(RevsetExpression::Range { Rc::new(RevsetExpression::Range {
roots: foo_symbol.clone(), roots: foo_symbol.clone(),
heads: wc_symbol.clone() heads: wc_symbol.clone(),
generation: GENERATION_RANGE_FULL,
}) })
); );
assert_eq!( assert_eq!(
@ -2672,6 +2726,7 @@ mod tests {
heads: Symbol( heads: Symbol(
"foo", "foo",
), ),
generation: 0..4294967295,
} }
"###); "###);
insta::assert_debug_snapshot!(optimize(parse("~:foo & :bar").unwrap()), @r###" insta::assert_debug_snapshot!(optimize(parse("~:foo & :bar").unwrap()), @r###"
@ -2682,6 +2737,7 @@ mod tests {
heads: Symbol( heads: Symbol(
"bar", "bar",
), ),
generation: 0..4294967295,
} }
"###); "###);
insta::assert_debug_snapshot!(optimize(parse("foo..").unwrap()), @r###" insta::assert_debug_snapshot!(optimize(parse("foo..").unwrap()), @r###"
@ -2690,6 +2746,7 @@ mod tests {
"foo", "foo",
), ),
heads: VisibleHeads, heads: VisibleHeads,
generation: 0..4294967295,
} }
"###); "###);
insta::assert_debug_snapshot!(optimize(parse("foo..bar").unwrap()), @r###" insta::assert_debug_snapshot!(optimize(parse("foo..bar").unwrap()), @r###"
@ -2700,6 +2757,7 @@ mod tests {
heads: Symbol( heads: Symbol(
"bar", "bar",
), ),
generation: 0..4294967295,
} }
"###); "###);