diff options
| author | 2026-03-06 21:19:56 +0800 | |
|---|---|---|
| committer | 2026-03-07 00:34:30 +0800 | |
| commit | 01d15bccf3b1dcc51516b1f64d50950b31d7f8fb (patch) | |
| tree | e491fcc762c67c1ef4ce54faafc5dafdb734ae8a /reachability/ancestor.go | |
| parent | objectstored/refstore: Weird ireturn behavior (diff) | |
| signature | No signature | |
Urgh I made some wrong amends and I'm too tired to separate the commits out this time
ancestor: Split out of reachability
mergebase: Add merge base routines
internal/commitquery: Add commit query context engine thingy
internal/peel: Shared tag peeling
errors: Shared object query errors
internal/testgit: Add rooted repo helpers; remove raw path access
objectstore/memory: Add in-memory object store
objectid: Add Compare helper
Diffstat (limited to 'reachability/ancestor.go')
| -rw-r--r-- | reachability/ancestor.go | 122 |
1 files changed, 0 insertions, 122 deletions
diff --git a/reachability/ancestor.go b/reachability/ancestor.go deleted file mode 100644 index 584ec0e3..00000000 --- a/reachability/ancestor.go +++ /dev/null @@ -1,122 +0,0 @@ -package reachability - -import ( - "errors" - - commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read" - "codeberg.org/lindenii/furgit/objectid" -) - -// IsAncestor reports whether ancestor is reachable from descendant via commit -// parent edges. -// -// Both inputs are peeled through annotated tags before commit traversal. -func (r *Reachability) IsAncestor(ancestor, descendant objectid.ObjectID) (bool, error) { - ancestorCommit, err := r.peelRootToCommit(ancestor) - if err != nil { - return false, err - } - - descendantCommit, err := r.peelRootToCommit(descendant) - if err != nil { - return false, err - } - - if ancestorCommit == descendantCommit { - return true, nil - } - - graphResult, graphUsed, err := r.isAncestorGraph(ancestorCommit, descendantCommit) - if err != nil { - return false, err - } - - if graphUsed { - return graphResult, nil - } - - walk := r.Walk(DomainCommits, nil, map[objectid.ObjectID]struct{}{descendantCommit: {}}) - for id := range walk.Seq() { - if id == ancestorCommit { - return true, nil - } - } - - err = walk.Err() - if err != nil { - return false, err - } - - return false, nil -} - -func (r *Reachability) isAncestorGraph(ancestor, descendant objectid.ObjectID) (bool, bool, error) { - if r.graph == nil { - return false, false, nil - } - - ancestorPos, err := r.graph.Lookup(ancestor) - if err != nil { - var notFound *commitgraphread.NotFoundError - if errors.As(err, ¬Found) { - return false, false, nil - } - - return false, true, err - } - - descendantPos, err := r.graph.Lookup(descendant) - if err != nil { - var notFound *commitgraphread.NotFoundError - if errors.As(err, ¬Found) { - return false, false, nil - } - - return false, true, err - } - - ancestorCommit, err := r.graph.CommitAt(ancestorPos) - if err != nil { - return false, true, err - } - - ancestorGeneration := ancestorCommit.GenerationV2 - stack := []commitgraphread.Position{descendantPos} - visited := make(map[commitgraphread.Position]struct{}, 64) - - for len(stack) > 0 { - pos := stack[len(stack)-1] - stack = stack[:len(stack)-1] - - if _, ok := visited[pos]; ok { - continue - } - - visited[pos] = struct{}{} - - if pos == ancestorPos { - return true, true, nil - } - - commit, err := r.graph.CommitAt(pos) - if err != nil { - return false, true, err - } - - if commit.GenerationV2 < ancestorGeneration { - continue - } - - if commit.Parent1.Valid { - stack = append(stack, commit.Parent1.Pos) - } - - if commit.Parent2.Valid { - stack = append(stack, commit.Parent2.Pos) - } - - stack = append(stack, commit.ExtraParents...) - } - - return false, true, nil -} |
