aboutsummaryrefslogtreecommitdiff
path: root/commitquery/oid.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-11 20:41:32 +0800
committerGravatar Runxi Yu2026-03-11 20:41:32 +0800
commit040b572d95e4ca27e1ada6113c405b8a1eb4a669 (patch)
tree68d826f4d91144105802c9d1c67175ba9b314e29 /commitquery/oid.go
parentresearch: Maybe drop mmap in packfile_bloom (diff)
signatureNo signature
commitquery: Merge from ancestor and mergebases
Diffstat (limited to 'commitquery/oid.go')
-rw-r--r--commitquery/oid.go101
1 files changed, 101 insertions, 0 deletions
diff --git a/commitquery/oid.go b/commitquery/oid.go
new file mode 100644
index 00000000..68adbf5d
--- /dev/null
+++ b/commitquery/oid.go
@@ -0,0 +1,101 @@
+package commitquery
+
+import (
+ stderrors "errors"
+
+ commitgraphread "codeberg.org/lindenii/furgit/commitgraph/read"
+ giterrors "codeberg.org/lindenii/furgit/errors"
+ "codeberg.org/lindenii/furgit/internal/peel"
+ "codeberg.org/lindenii/furgit/object"
+ "codeberg.org/lindenii/furgit/objectid"
+ "codeberg.org/lindenii/furgit/objectstore"
+ "codeberg.org/lindenii/furgit/objecttype"
+)
+
+func (query *Query) id(idx nodeIndex) objectid.ObjectID {
+ return query.nodes[idx].id
+}
+
+func (query *Query) commitTime(idx nodeIndex) int64 {
+ return query.nodes[idx].commitTime
+}
+
+func (query *Query) resolveOID(id objectid.ObjectID) (nodeIndex, error) {
+ idx, ok := query.byOID[id]
+ if ok {
+ err := query.ensureLoaded(idx)
+ if err != nil {
+ return 0, err
+ }
+
+ return idx, nil
+ }
+
+ idx = query.newNode(id)
+ query.byOID[id] = idx
+
+ err := query.loadByOID(idx)
+ if err != nil {
+ delete(query.byOID, id)
+
+ return 0, err
+ }
+
+ return idx, nil
+}
+
+func (query *Query) resolveCommitish(id objectid.ObjectID) (nodeIndex, error) {
+ commitID, err := peel.ToCommit(query.store, id)
+ if err != nil {
+ return 0, err
+ }
+
+ return query.resolveOID(commitID)
+}
+
+// loadByOID populates one node from an object ID.
+func (query *Query) loadByOID(idx nodeIndex) error {
+ id := query.nodes[idx].id
+
+ if query.graph != nil {
+ pos, err := query.graph.Lookup(id)
+ if err != nil {
+ if _, ok := stderrors.AsType[*commitgraphread.NotFoundError](err); !ok {
+ return err
+ }
+ } else {
+ return query.loadCommitAtGraphPos(idx, pos)
+ }
+ }
+
+ ty, content, err := query.store.ReadBytesContent(id)
+ if err != nil {
+ if stderrors.Is(err, objectstore.ErrObjectNotFound) {
+ return &giterrors.ObjectMissingError{OID: id}
+ }
+
+ return err
+ }
+
+ if ty != objecttype.TypeCommit {
+ return &giterrors.ObjectTypeError{OID: id, Got: ty, Want: objecttype.TypeCommit}
+ }
+
+ commitObj, err := object.ParseCommit(content, id.Algorithm())
+ if err != nil {
+ return err
+ }
+
+ parents := make([]parentRef, 0, len(commitObj.Parents))
+ for _, parentID := range commitObj.Parents {
+ parents = append(parents, parentRef{ID: parentID})
+ }
+
+ commit := commitData{
+ ID: id,
+ Parents: parents,
+ CommitTime: commitObj.Committer.WhenUnix,
+ }
+
+ return query.populateNode(idx, commit)
+}