shithub: furgit

Download patch

ref: ecdae2b758ef6849222525c941574bbac13ea85c
parent: df73a4c6f1b58075316ba7449fbfb127b9fbb79d
author: Runxi Yu <runxiyu@umich.edu>
date: Sun Mar 29 11:00:06 EDT 2026

commitquery: Use fetcher

--- a/commitquery/queries.go
+++ b/commitquery/queries.go
@@ -4,10 +4,10 @@
 	"sync"
 
 	commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read"
-	objectstore "codeberg.org/lindenii/furgit/object/store"
+	objectfetch "codeberg.org/lindenii/furgit/object/fetch"
 )
 
-// Queries provides commit-domain queries over one object store
+// Queries provides commit-domain queries over one object fetcher
 // and optional commit-graph reader.
 //
 // Queries reuses internal mutable query workers across operations.
@@ -14,8 +14,8 @@
 //
 // Labels: MT-Safe.
 type Queries struct {
-	store objectstore.ReadingStore
-	graph *commitgraphread.Reader
+	fetcher *objectfetch.Fetcher
+	graph   *commitgraphread.Reader
 
 	mu      sync.Mutex
 	idle    []*query
--- a/commitquery/queries_acquire.go
+++ b/commitquery/queries_acquire.go
@@ -7,7 +7,7 @@
 
 	count := len(queries.idle)
 	if count == 0 {
-		return newQuery(queries.store, queries.graph)
+		return newQuery(queries.fetcher, queries.graph)
 	}
 
 	q := queries.idle[count-1]
--- a/commitquery/queries_is_ancestor_integration_test.go
+++ b/commitquery/queries_is_ancestor_integration_test.go
@@ -7,6 +7,7 @@
 	"codeberg.org/lindenii/furgit/commitquery"
 	giterrors "codeberg.org/lindenii/furgit/errors"
 	"codeberg.org/lindenii/furgit/internal/testgit"
+	"codeberg.org/lindenii/furgit/object/fetch"
 	objectid "codeberg.org/lindenii/furgit/object/id"
 )
 
@@ -33,7 +34,7 @@
 
 		store := testRepo.OpenObjectStore(t)
 
-		got, err := commitquery.New(store, nil).IsAncestor(c1, tag)
+		got, err := commitquery.New(fetch.New(store), nil).IsAncestor(c1, tag)
 		if err != nil {
 			t.Fatalf("Is(c1, tag): %v", err)
 		}
@@ -43,7 +44,7 @@
 			t.Fatalf("Is(c1, tag)=%v, want %v", got, want)
 		}
 
-		got, err = commitquery.New(store, nil).IsAncestor(c3, c2)
+		got, err = commitquery.New(fetch.New(store), nil).IsAncestor(c3, c2)
 		if err != nil {
 			t.Fatalf("Is(c3, c2): %v", err)
 		}
@@ -78,7 +79,7 @@
 		store := testRepo.OpenObjectStore(t)
 		graph := testRepo.OpenCommitGraph(t)
 
-		got, err := commitquery.New(store, graph).IsAncestor(c1, c2)
+		got, err := commitquery.New(fetch.New(store), graph).IsAncestor(c1, c2)
 		if err != nil {
 			t.Fatalf("Is(c1, c2): %v", err)
 		}
@@ -106,7 +107,7 @@
 
 		store := testRepo.OpenObjectStore(t)
 
-		_, err := commitquery.New(store, nil).IsAncestor(treeID, commitID)
+		_, err := commitquery.New(fetch.New(store), nil).IsAncestor(treeID, commitID)
 		if err == nil {
 			t.Fatal("expected error")
 		}
--- a/commitquery/queries_is_ancestor_unit_test.go
+++ b/commitquery/queries_is_ancestor_unit_test.go
@@ -7,6 +7,7 @@
 
 	giterrors "codeberg.org/lindenii/furgit/errors"
 	"codeberg.org/lindenii/furgit/internal/testgit"
+	"codeberg.org/lindenii/furgit/object/fetch"
 	objectid "codeberg.org/lindenii/furgit/object/id"
 	"codeberg.org/lindenii/furgit/object/store/memory"
 	objecttree "codeberg.org/lindenii/furgit/object/tree"
@@ -71,7 +72,7 @@
 		c3 := store.AddObject(objecttype.TypeCommit, ancestorCommitBody(otherTree))
 		tag := store.AddObject(objecttype.TypeTag, ancestorTagBody(c2, objecttype.TypeCommit))
 
-		ok, err := commitquery.New(store, nil).IsAncestor(c1, tag)
+		ok, err := commitquery.New(fetch.New(store), nil).IsAncestor(c1, tag)
 		if err != nil {
 			t.Fatalf("Is(c1, tag): %v", err)
 		}
@@ -80,7 +81,7 @@
 			t.Fatal("expected c1 to be ancestor of tag->c2")
 		}
 
-		ok, err = commitquery.New(store, nil).IsAncestor(c3, c2)
+		ok, err = commitquery.New(fetch.New(store), nil).IsAncestor(c3, c2)
 		if err != nil {
 			t.Fatalf("Is(c3, c2): %v", err)
 		}
@@ -105,7 +106,7 @@
 		commit := store.AddObject(objecttype.TypeCommit, ancestorCommitBody(tree))
 		tagToTree := store.AddObject(objecttype.TypeTag, ancestorTagBody(tree, objecttype.TypeTree))
 
-		_, err := commitquery.New(store, nil).IsAncestor(commit, tagToTree)
+		_, err := commitquery.New(fetch.New(store), nil).IsAncestor(commit, tagToTree)
 		if err == nil {
 			t.Fatal("expected error")
 		}
--- a/commitquery/queries_merge_bases_integration_test.go
+++ b/commitquery/queries_merge_bases_integration_test.go
@@ -8,6 +8,7 @@
 
 	"codeberg.org/lindenii/furgit/commitquery"
 	"codeberg.org/lindenii/furgit/internal/testgit"
+	"codeberg.org/lindenii/furgit/object/fetch"
 	objectid "codeberg.org/lindenii/furgit/object/id"
 )
 
@@ -34,7 +35,7 @@
 
 		store := testRepo.OpenObjectStore(t)
 
-		query := commitquery.New(store, nil)
+		query := commitquery.New(fetch.New(store), nil)
 
 		all, err := query.MergeBases(left, tag)
 		if err != nil {
@@ -77,7 +78,7 @@
 
 		store := testRepo.OpenObjectStore(t)
 
-		query := commitquery.New(store, nil)
+		query := commitquery.New(fetch.New(store), nil)
 
 		all, err := query.MergeBases(left, right)
 		if err != nil {
@@ -138,7 +139,7 @@
 		store := testRepo.OpenObjectStore(t)
 		graph := testRepo.OpenCommitGraph(t)
 
-		query := commitquery.New(store, graph)
+		query := commitquery.New(fetch.New(store), graph)
 
 		all, err := query.MergeBases(left, right)
 		if err != nil {
@@ -200,7 +201,7 @@
 
 		store := testRepo.OpenObjectStore(t)
 
-		query := commitquery.New(store, nil)
+		query := commitquery.New(fetch.New(store), nil)
 
 		got, ok, err := query.MergeBase(left, right)
 		if err != nil {
@@ -222,7 +223,7 @@
 
 		graph := testRepo.OpenCommitGraph(t)
 
-		got, ok, err = commitquery.New(store, graph).MergeBase(left, right)
+		got, ok, err = commitquery.New(fetch.New(store), graph).MergeBase(left, right)
 		if err != nil {
 			t.Fatalf("Base(left, right) with commit-graph: %v", err)
 		}
--- a/commitquery/queries_merge_bases_unit_test.go
+++ b/commitquery/queries_merge_bases_unit_test.go
@@ -10,6 +10,7 @@
 	"codeberg.org/lindenii/furgit/commitquery"
 	giterrors "codeberg.org/lindenii/furgit/errors"
 	"codeberg.org/lindenii/furgit/internal/testgit"
+	"codeberg.org/lindenii/furgit/object/fetch"
 	objectid "codeberg.org/lindenii/furgit/object/id"
 	"codeberg.org/lindenii/furgit/object/store/memory"
 	"codeberg.org/lindenii/furgit/object/tree"
@@ -83,7 +84,7 @@
 		left := store.AddObject(objecttype.TypeCommit, commitBody(tree, base))
 		right := store.AddObject(objecttype.TypeCommit, commitBody(tree, left))
 
-		query := commitquery.New(store, nil)
+		query := commitquery.New(fetch.New(store), nil)
 
 		got, err := query.MergeBases(left, right)
 		if err != nil {
@@ -130,7 +131,7 @@
 		right := store.AddObject(objecttype.TypeCommit, commitBody(rightTree, base))
 		tag := store.AddObject(objecttype.TypeTag, tagBody(right, objecttype.TypeCommit))
 
-		query := commitquery.New(store, nil)
+		query := commitquery.New(fetch.New(store), nil)
 
 		got, err := query.MergeBases(left, tag)
 		if err != nil {
@@ -180,7 +181,7 @@
 		left := store.AddObject(objecttype.TypeCommit, commitBody(leftTree, base1, base2))
 		right := store.AddObject(objecttype.TypeCommit, commitBody(rightTree, base2, base1))
 
-		query := commitquery.New(store, nil)
+		query := commitquery.New(fetch.New(store), nil)
 
 		all, err := query.MergeBases(left, right)
 		if err != nil {
@@ -229,7 +230,7 @@
 		left := store.AddObject(objecttype.TypeCommit, commitBody(leftTree))
 		right := store.AddObject(objecttype.TypeCommit, commitBody(rightTree))
 
-		query := commitquery.New(store, nil)
+		query := commitquery.New(fetch.New(store), nil)
 
 		got, err := query.MergeBases(left, right)
 		if err != nil {
@@ -265,7 +266,7 @@
 		commit := store.AddObject(objecttype.TypeCommit, commitBody(tree))
 		tagToTree := store.AddObject(objecttype.TypeTag, tagBody(tree, objecttype.TypeTree))
 
-		query := commitquery.New(store, nil)
+		query := commitquery.New(fetch.New(store), nil)
 
 		_, err := query.MergeBases(commit, tagToTree)
 		if err == nil {
@@ -298,7 +299,7 @@
 		left := store.AddObject(objecttype.TypeCommit, commitBody(tree, base))
 		right := store.AddObject(objecttype.TypeCommit, commitBody(tree, left))
 
-		query := commitquery.New(store, nil)
+		query := commitquery.New(fetch.New(store), nil)
 
 		first, err := query.MergeBases(left, right)
 		if err != nil {
--- a/commitquery/queries_new.go
+++ b/commitquery/queries_new.go
@@ -4,18 +4,18 @@
 	"runtime"
 
 	commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read"
-	objectstore "codeberg.org/lindenii/furgit/object/store"
+	objectfetch "codeberg.org/lindenii/furgit/object/fetch"
 )
 
-// New builds one concurrent-safe commit query service over one object store
+// New builds one concurrent-safe commit query service over one object fetcher
 // and optional commit-graph reader.
 //
 // Labels: Deps-Borrowed, Life-Parent.
-func New(store objectstore.ReadingStore, graph *commitgraphread.Reader) *Queries {
+func New(fetcher *objectfetch.Fetcher, graph *commitgraphread.Reader) *Queries {
 	maxIdle := max(runtime.GOMAXPROCS(0), 1)
 
 	return &Queries{
-		store:   store,
+		fetcher: fetcher,
 		graph:   graph,
 		maxIdle: maxIdle,
 	}
--- a/commitquery/query.go
+++ b/commitquery/query.go
@@ -2,8 +2,8 @@
 
 import (
 	commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read"
+	objectfetch "codeberg.org/lindenii/furgit/object/fetch"
 	objectid "codeberg.org/lindenii/furgit/object/id"
-	objectstore "codeberg.org/lindenii/furgit/object/store"
 )
 
 // query stores one mutable reusable worker and its cached node arena.
@@ -10,8 +10,8 @@
 //
 // Labels: MT-Unsafe.
 type query struct {
-	store objectstore.ReadingStore
-	graph *commitgraphread.Reader
+	fetcher *objectfetch.Fetcher
+	graph   *commitgraphread.Reader
 
 	nodes []node
 
--- a/commitquery/query_load_by_oid.go
+++ b/commitquery/query_load_by_oid.go
@@ -5,7 +5,7 @@
 
 	giterrors "codeberg.org/lindenii/furgit/errors"
 	commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read"
-	objectcommit "codeberg.org/lindenii/furgit/object/commit"
+	"codeberg.org/lindenii/furgit/object/commit"
 	objectstore "codeberg.org/lindenii/furgit/object/store"
 	objecttype "codeberg.org/lindenii/furgit/object/type"
 )
@@ -25,7 +25,7 @@
 		}
 	}
 
-	ty, content, err := query.store.ReadBytesContent(id)
+	obj, err := query.fetcher.ExactObject(id)
 	if err != nil {
 		if stderrors.Is(err, objectstore.ErrObjectNotFound) {
 			return &giterrors.ObjectMissingError{OID: id}
@@ -34,13 +34,13 @@
 		return err
 	}
 
-	if ty != objecttype.TypeCommit {
-		return &giterrors.ObjectTypeError{OID: id, Got: ty, Want: objecttype.TypeCommit}
-	}
-
-	commitObj, err := objectcommit.Parse(content, id.Algorithm())
-	if err != nil {
-		return err
+	commitObj, ok := obj.Object().(*commit.Commit)
+	if !ok {
+		return &giterrors.ObjectTypeError{
+			OID:  id,
+			Got:  obj.Object().ObjectType(),
+			Want: objecttype.TypeCommit,
+		}
 	}
 
 	parents := make([]parentRef, 0, len(commitObj.Parents))
--- a/commitquery/query_new.go
+++ b/commitquery/query_new.go
@@ -2,16 +2,16 @@
 
 import (
 	commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read"
+	objectfetch "codeberg.org/lindenii/furgit/object/fetch"
 	objectid "codeberg.org/lindenii/furgit/object/id"
-	objectstore "codeberg.org/lindenii/furgit/object/store"
 )
 
-// newQuery builds one empty mutable worker over one object store and graph.
+// newQuery builds one empty mutable worker over one object fetcher and graph.
 //
 // Labels: Deps-Borrowed, Life-Parent.
-func newQuery(store objectstore.ReadingStore, graph *commitgraphread.Reader) *query {
+func newQuery(fetcher *objectfetch.Fetcher, graph *commitgraphread.Reader) *query {
 	return &query{
-		store:      store,
+		fetcher:    fetcher,
 		graph:      graph,
 		byOID:      make(map[objectid.ObjectID]nodeIndex),
 		byGraphPos: make(map[commitgraphread.Position]nodeIndex),
--- a/commitquery/query_resolve_commitish.go
+++ b/commitquery/query_resolve_commitish.go
@@ -1,16 +1,39 @@
 package commitquery
 
 import (
-	"codeberg.org/lindenii/furgit/internal/peel"
+	stderrors "errors"
+
+	giterrors "codeberg.org/lindenii/furgit/errors"
+	"codeberg.org/lindenii/furgit/object/commit"
 	objectid "codeberg.org/lindenii/furgit/object/id"
+	objectstore "codeberg.org/lindenii/furgit/object/store"
+	"codeberg.org/lindenii/furgit/object/tag"
+	objecttype "codeberg.org/lindenii/furgit/object/type"
 )
 
 // resolveCommitish peels one commit-ish object ID and resolves the commit.
 func (query *query) resolveCommitish(id objectid.ObjectID) (nodeIndex, error) {
-	commitID, err := peel.ToCommit(query.store, id)
-	if err != nil {
-		return 0, err
-	}
+	for {
+		obj, err := query.fetcher.ExactObject(id)
+		if err != nil {
+			if stderrors.Is(err, objectstore.ErrObjectNotFound) {
+				return 0, &giterrors.ObjectMissingError{OID: id}
+			}
 
-	return query.resolveOID(commitID)
+			return 0, err
+		}
+
+		switch parsed := obj.Object().(type) {
+		case *commit.Commit:
+			return query.resolveOID(id)
+		case *tag.Tag:
+			id = parsed.Target
+		default:
+			return 0, &giterrors.ObjectTypeError{
+				OID:  id,
+				Got:  parsed.ObjectType(),
+				Want: objecttype.TypeCommit,
+			}
+		}
+	}
 }
--- a/network/receivepack/hooks/reject_force_push.go
+++ b/network/receivepack/hooks/reject_force_push.go
@@ -7,6 +7,7 @@
 
 	"codeberg.org/lindenii/furgit/commitquery"
 	receivepack "codeberg.org/lindenii/furgit/network/receivepack"
+	"codeberg.org/lindenii/furgit/object/fetch"
 	objectmix "codeberg.org/lindenii/furgit/object/store/mix"
 	refstore "codeberg.org/lindenii/furgit/ref/store"
 )
@@ -24,7 +25,7 @@
 
 		defer func() { _ = objects.Close() }()
 
-		queries := commitquery.New(objects, req.CommitGraph)
+		queries := commitquery.New(fetch.New(objects), req.CommitGraph)
 
 		decisions := make([]receivepack.UpdateDecision, len(req.Updates))
 		for i := range decisions {
--- a/repository/fetcher.go
+++ b/repository/fetcher.go
@@ -10,5 +10,5 @@
 //
 // Labels: Life-Parent, Close-No.
 func (repo *Repository) Fetcher() *fetch.Fetcher {
-	return fetch.New(repo.objects)
+	return repo.fetcher
 }
--- a/repository/open.go
+++ b/repository/open.go
@@ -5,6 +5,7 @@
 	"os"
 
 	"codeberg.org/lindenii/furgit/commitquery"
+	"codeberg.org/lindenii/furgit/object/fetch"
 	reffiles "codeberg.org/lindenii/furgit/ref/store/files"
 )
 
@@ -44,6 +45,7 @@
 	}
 
 	repo.objects = objects
+	repo.fetcher = fetch.New(objects)
 	repo.objectsRoot = objectsRoot
 	repo.objectsPackRoot = objectsPackRoot
 	repo.objectsLoose = objectsLoose
@@ -55,7 +57,7 @@
 	}
 
 	repo.commitGraph = commitGraph
-	repo.commitQueries = commitquery.New(objects, commitGraph)
+	repo.commitQueries = commitquery.New(repo.fetcher, commitGraph)
 
 	refRoot, err := root.OpenRoot(".")
 	if err != nil {
--- a/repository/repository.go
+++ b/repository/repository.go
@@ -13,6 +13,7 @@
 	"codeberg.org/lindenii/furgit/commitquery"
 	"codeberg.org/lindenii/furgit/config"
 	commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read"
+	"codeberg.org/lindenii/furgit/object/fetch"
 	objectid "codeberg.org/lindenii/furgit/object/id"
 	objectstore "codeberg.org/lindenii/furgit/object/store"
 	objectloose "codeberg.org/lindenii/furgit/object/store/loose"
@@ -32,6 +33,7 @@
 	algo   objectid.Algorithm
 
 	objects         objectstore.ReadingStore
+	fetcher         *fetch.Fetcher
 	objectsRoot     *os.Root
 	objectsPackRoot *os.Root
 	objectsLoose    *objectloose.Store
--