diff options
| author | 2026-03-06 21:19:56 +0800 | |
|---|---|---|
| committer | 2026-03-07 00:34:30 +0800 | |
| commit | 01d15bccf3b1dcc51516b1f64d50950b31d7f8fb (patch) | |
| tree | e491fcc762c67c1ef4ce54faafc5dafdb734ae8a /internal/peel | |
| 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 'internal/peel')
| -rw-r--r-- | internal/peel/peel.go | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/internal/peel/peel.go b/internal/peel/peel.go new file mode 100644 index 00000000..a3e84b8d --- /dev/null +++ b/internal/peel/peel.go @@ -0,0 +1,50 @@ +// Package peel peels Git object references through annotated tags. +package peel + +import ( + stderrors "errors" + + giterrors "codeberg.org/lindenii/furgit/errors" + "codeberg.org/lindenii/furgit/object" + "codeberg.org/lindenii/furgit/objectid" + "codeberg.org/lindenii/furgit/objectstore" + "codeberg.org/lindenii/furgit/objecttype" +) + +// ToCommit peels annotated tags transitively until a commit is reached. +func ToCommit(store objectstore.Store, id objectid.ObjectID) (objectid.ObjectID, error) { + for { + ty, _, err := store.ReadHeader(id) + if err != nil { + if stderrors.Is(err, objectstore.ErrObjectNotFound) { + return objectid.ObjectID{}, &giterrors.ObjectMissingError{OID: id} + } + + return objectid.ObjectID{}, err + } + + if ty != objecttype.TypeTag { + if ty != objecttype.TypeCommit { + return objectid.ObjectID{}, &giterrors.ObjectTypeError{OID: id, Got: ty, Want: objecttype.TypeCommit} + } + + return id, nil + } + + _, content, err := store.ReadBytesContent(id) + if err != nil { + if stderrors.Is(err, objectstore.ErrObjectNotFound) { + return objectid.ObjectID{}, &giterrors.ObjectMissingError{OID: id} + } + + return objectid.ObjectID{}, err + } + + tag, err := object.ParseTag(content, id.Algorithm()) + if err != nil { + return objectid.ObjectID{}, err + } + + id = tag.Target + } +} |
