From da218d19dbb680f69ed6da65e8e8d357ec694ecb Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Sun, 14 Jan 2024 19:35:28 +0900 Subject: [PATCH] repo: optimize enforce_view_invariants() to not traverse ancestors until root Because the default index cuts off the traversal at min(generations), including the root id means all ancestors will be visited. This could be worked around at the index side, but I think it's the repo/view's responsibility. That being said, it's not uncommon to pad a revset with "root()", so it might make sense for the index to special case the root id. I also removed the redundant .clone(). --- lib/src/repo.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/src/repo.rs b/lib/src/repo.rs index e20d37051..07b48cc0e 100644 --- a/lib/src/repo.rs +++ b/lib/src/repo.rs @@ -1017,13 +1017,20 @@ impl MutableRepo { fn enforce_view_invariants(&self, view: &mut View) { let view = view.store_view_mut(); - view.head_ids.insert(self.store().root_commit_id().clone()); - view.head_ids = self - .index() - .heads(&mut view.head_ids.iter()) - .iter() - .cloned() - .collect(); + let root_commit_id = self.store().root_commit_id(); + if view.head_ids.is_empty() { + view.head_ids.insert(root_commit_id.clone()); + } else if view.head_ids.len() > 1 { + // An empty head_ids set is padded with the root_commit_id, but the + // root id is unwanted during the heads resolution. + view.head_ids.remove(root_commit_id); + view.head_ids = self + .index() + .heads(&mut view.head_ids.iter()) + .into_iter() + .collect(); + } + assert!(!view.head_ids.is_empty()); } /// Ensures that the given `head` and ancestor commits are reachable from