From 85fb1f74c300483a9931c93554c3703466e426c3 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Thu, 6 Apr 2023 18:43:39 +0900 Subject: [PATCH] revset: for roots:heads, terminate ancestor lookup at min(roots) --- lib/src/default_revset_engine.rs | 9 +++++++-- lib/tests/test_revset.rs | 24 ++++++++++++++++++++++++ testing/bench-revsets-git.txt | 1 + 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/src/default_revset_engine.rs b/lib/src/default_revset_engine.rs index 2a76b5d62..b09e65703 100644 --- a/lib/src/default_revset_engine.rs +++ b/lib/src/default_revset_engine.rs @@ -825,9 +825,14 @@ impl<'index, 'heads> EvaluationContext<'index, 'heads> { S: InternalRevset<'a> + ?Sized, T: InternalRevset<'b> + ?Sized, { - let mut reachable: HashSet<_> = root_set.iter().map(|entry| entry.position()).collect(); + let root_positions = root_set.iter().map(|entry| entry.position()).collect_vec(); + let bottom_position = *root_positions.last().unwrap_or(&IndexPosition::MAX); + let mut reachable: HashSet<_> = root_positions.into_iter().collect(); let mut index_entries = vec![]; - let candidates = self.walk_ancestors(head_set).collect_vec(); + let candidates = self + .walk_ancestors(head_set) + .take_while(|entry| entry.position() >= bottom_position) + .collect_vec(); for candidate in candidates.into_iter().rev() { if reachable.contains(&candidate.position()) || candidate diff --git a/lib/tests/test_revset.rs b/lib/tests/test_revset.rs index b927050ce..9b5891835 100644 --- a/lib/tests/test_revset.rs +++ b/lib/tests/test_revset.rs @@ -976,6 +976,30 @@ fn test_evaluate_expression_dag_range(use_git: bool) { vec![] ); + // Empty root + assert_eq!( + resolve_commit_ids(mut_repo, &format!("none():{}", commit5.id().hex())), + vec![], + ); + + // Multiple root, commit1 shouldn't be hidden by commit2 + assert_eq!( + resolve_commit_ids( + mut_repo, + &format!( + "({}|{}):{}", + commit1.id().hex(), + commit2.id().hex(), + commit3.id().hex() + ) + ), + vec![ + commit3.id().clone(), + commit2.id().clone(), + commit1.id().clone() + ] + ); + // Including a merge assert_eq!( resolve_commit_ids( diff --git a/testing/bench-revsets-git.txt b/testing/bench-revsets-git.txt index e901c9b3e..4f9817b90 100644 --- a/testing/bench-revsets-git.txt +++ b/testing/bench-revsets-git.txt @@ -13,6 +13,7 @@ v2.40.0 v2.39.0..v2.40.0 :v2.40.0 ~ :v2.39.0 v2.39.0:v2.40.0 +v2.40.0+ # Tags and branches tags() branches()