revset: make empty()/file(".") not load root tree for liner history

TreeDiffIterator wouldn't load identical subtrees, but it's up to caller to
optimize out the root tree loading.
This commit is contained in:
Yuya Nishihara 2023-04-05 16:19:32 +09:00
parent feeb83dc0f
commit 308a5b9eae
2 changed files with 12 additions and 1 deletions

View file

@ -24,7 +24,8 @@ use crate::backend::{ChangeId, CommitId, MillisSinceEpoch, ObjectId};
use crate::default_index_store::{CompositeIndex, IndexEntry, IndexEntryByPosition, IndexPosition};
use crate::default_revset_graph_iterator::RevsetGraphIterator;
use crate::index::{HexPrefix, Index, PrefixResolution};
use crate::matchers::{EverythingMatcher, Matcher, PrefixMatcher};
use crate::matchers::{EverythingMatcher, Matcher, PrefixMatcher, Visit};
use crate::repo_path::RepoPath;
use crate::revset::{
ChangeIdIndex, Revset, RevsetEvaluationError, RevsetExpression, RevsetFilterPredicate,
RevsetGraphEdge, GENERATION_RANGE_FULL,
@ -954,6 +955,15 @@ fn has_diff_from_parent(
) -> bool {
let commit = store.get_commit(&entry.commit_id()).unwrap();
let parents = commit.parents();
if let [parent] = parents.as_slice() {
// Fast path: no need to load the root tree
let unchanged = commit.tree_id() == parent.tree_id();
if matcher.visit(&RepoPath::root()) == Visit::AllRecursively {
return !unchanged;
} else if unchanged {
return false;
}
}
let from_tree = rewrite::merge_commit_trees_without_repo(store, index, &parents);
let to_tree = commit.tree();
from_tree.diff(&to_tree, matcher).next().is_some()

View file

@ -45,3 +45,4 @@ merges()
~merges()
# Files are unbearably slow, so only filter within small set
file(Makefile) & v1.0.0..v1.2.0
empty() & v1.0.0..v1.2.0