aboutsummaryrefslogtreecommitdiffstats
path: root/core/reference.go
diff options
context:
space:
mode:
Diffstat (limited to 'core/reference.go')
-rw-r--r--core/reference.go31
1 files changed, 30 insertions, 1 deletions
diff --git a/core/reference.go b/core/reference.go
index ec00787..4be4971 100644
--- a/core/reference.go
+++ b/core/reference.go
@@ -13,10 +13,13 @@ const (
refRemotePrefix = refPrefix + "remotes/"
refNotePrefix = refPrefix + "notes/"
symrefPrefix = "ref: "
+
+ maxResolveRecursion = 1024
)
var (
- ErrReferenceNotFound = errors.New("reference not found")
+ ErrMaxResolveRecursion = errors.New("max. recursion level reached")
+ ErrReferenceNotFound = errors.New("reference not found")
)
// ReferenceType reference type's
@@ -150,3 +153,29 @@ func (iter *ReferenceSliceIter) Next() (*Reference, error) {
func (iter *ReferenceSliceIter) Close() {
iter.pos = len(iter.series)
}
+
+func ResolveReference(s ReferenceStorage, n ReferenceName) (*Reference, error) {
+ r, err := s.Get(n)
+ if err != nil || r == nil {
+ return r, err
+ }
+ return resolveReference(s, r, 0)
+}
+
+func resolveReference(s ReferenceStorage, r *Reference, recursion int) (*Reference, error) {
+ if r.Type() != SymbolicReference {
+ return r, nil
+ }
+
+ if recursion > maxResolveRecursion {
+ return nil, ErrMaxResolveRecursion
+ }
+
+ t, err := s.Get(r.Target())
+ if err != nil {
+ return nil, err
+ }
+
+ recursion++
+ return resolveReference(s, t, recursion)
+}