From 040b572d95e4ca27e1ada6113c405b8a1eb4a669 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Wed, 11 Mar 2026 20:41:32 +0800 Subject: commitquery: Merge from ancestor and mergebases --- commitquery/ancestor.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 commitquery/ancestor.go (limited to 'commitquery/ancestor.go') diff --git a/commitquery/ancestor.go b/commitquery/ancestor.go new file mode 100644 index 00000000..671ea460 --- /dev/null +++ b/commitquery/ancestor.go @@ -0,0 +1,48 @@ +package commitquery + +import "codeberg.org/lindenii/furgit/objectid" + +// IsAncestor reports whether ancestor is reachable from descendant through +// commit parent edges. +// +// Both inputs are peeled through annotated tags before commit traversal. +func (query *Query) IsAncestor(ancestor, descendant objectid.ObjectID) (bool, error) { + ancestorIdx, err := query.resolveCommitish(ancestor) + if err != nil { + return false, err + } + + descendantIdx, err := query.resolveCommitish(descendant) + if err != nil { + return false, err + } + + return query.isAncestor(ancestorIdx, descendantIdx) +} + +func (query *Query) isAncestor(ancestor, descendant nodeIndex) (bool, error) { + if ancestor == descendant { + return true, nil + } + + ancestorGeneration := query.effectiveGeneration(ancestor) + descendantGeneration := query.effectiveGeneration(descendant) + + if ancestorGeneration != generationInfinity && + descendantGeneration != generationInfinity && + ancestorGeneration > descendantGeneration { + return false, nil + } + + minGeneration := uint64(0) + if ancestorGeneration != generationInfinity { + minGeneration = ancestorGeneration + } + + err := query.paintDownToCommon(ancestor, []nodeIndex{descendant}, minGeneration) + if err != nil { + return false, err + } + + return query.hasAnyMarks(ancestor, markRight), nil +} -- cgit v1.3.1-10-gc9f91