Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit f0b12f7

Browse files
committed
core: Reference logic implementation, and InvalidObject ObjectType
1 parent d66fcf8 commit f0b12f7

File tree

2 files changed

+181
-0
lines changed

2 files changed

+181
-0
lines changed

core/reference.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package core
2+
3+
import "strings"
4+
5+
const (
6+
refPrefix = "refs/"
7+
refHeadPrefix = refPrefix + "heads/"
8+
refTagPrefix = refPrefix + "tags/"
9+
refRemotePrefix = refPrefix + "remotes/"
10+
refNotePrefix = refPrefix + "notes/"
11+
symrefPrefix = "ref: "
12+
)
13+
14+
// ReferenceType reference type's
15+
type ReferenceType int8
16+
17+
const (
18+
InvalidReference ReferenceType = 0
19+
HashReference ReferenceType = 1
20+
SymbolicReference ReferenceType = 2
21+
)
22+
23+
// ReferenceName reference name's
24+
type ReferenceName string
25+
26+
const (
27+
HEAD ReferenceName = "HEAD"
28+
)
29+
30+
// Reference is a representation of git reference
31+
type Reference struct {
32+
t ReferenceType
33+
n ReferenceName
34+
h Hash
35+
target ReferenceName
36+
}
37+
38+
// NewReferenceFromStrings creates a reference from name and target as string,
39+
// the resulting reference can be a SymbolicReference or a HashReference base
40+
// on the target provided
41+
func NewReferenceFromStrings(name, target string) *Reference {
42+
r := &Reference{n: ReferenceName(name)}
43+
44+
if strings.HasPrefix(target, symrefPrefix) {
45+
r.t = SymbolicReference
46+
r.target = ReferenceName(target[len(symrefPrefix):])
47+
return r
48+
}
49+
50+
r.t = HashReference
51+
r.h = NewHash(target)
52+
return r
53+
}
54+
55+
// NewSymbolicReference creates a new SymbolicReference reference
56+
func NewSymbolicReference(n, target ReferenceName) *Reference {
57+
return &Reference{
58+
t: SymbolicReference,
59+
n: n,
60+
target: target,
61+
}
62+
}
63+
64+
// NewHashReference creates a new HashReference reference
65+
func NewHashReference(n ReferenceName, h Hash) *Reference {
66+
return &Reference{
67+
t: HashReference,
68+
n: n,
69+
h: h,
70+
}
71+
}
72+
73+
// Type return the type of a reference
74+
func (r *Reference) Type() ReferenceType {
75+
return r.t
76+
}
77+
78+
// Name return the name of a reference
79+
func (r *Reference) Name() ReferenceName {
80+
return r.n
81+
}
82+
83+
// Hash return the hash of a hash reference
84+
func (r *Reference) Hash() Hash {
85+
return r.h
86+
}
87+
88+
// Target return the target of a symbolic reference
89+
func (r *Reference) Target() ReferenceName {
90+
return r.target
91+
}
92+
93+
// IsBranch check if a reference is a branch
94+
func (r *Reference) IsBranch() bool {
95+
return strings.HasPrefix(string(r.n), refHeadPrefix)
96+
}
97+
98+
// IsNote check if a reference is a note
99+
func (r *Reference) IsNote() bool {
100+
return strings.HasPrefix(string(r.n), refNotePrefix)
101+
}
102+
103+
// IsRemote check if a reference is a remote
104+
func (r *Reference) IsRemote() bool {
105+
return strings.HasPrefix(string(r.n), refRemotePrefix)
106+
}
107+
108+
// IsTag check if a reference is a tag
109+
func (r *Reference) IsTag() bool {
110+
return strings.HasPrefix(string(r.n), refTagPrefix)
111+
}
112+
113+
// ReferenceStorage generic storage of references
114+
type ReferenceStorage interface {
115+
Set(Reference) error
116+
Get(ReferenceName) (Reference, error)
117+
Iter(ObjectType) (ReferenceIter, error)
118+
}
119+
120+
// ReferenceIter is a generic closable interface for iterating over references
121+
type ReferenceIter interface {
122+
Next() (Reference, error)
123+
Close()
124+
}

core/reference_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package core
2+
3+
import . "gopkg.in/check.v1"
4+
5+
type ReferenceSuite struct{}
6+
7+
var _ = Suite(&ReferenceSuite{})
8+
9+
const (
10+
ExampleReferenceName ReferenceName = "refs/heads/v4"
11+
)
12+
13+
func (s *ReferenceSuite) TestNewReferenceFromStrings(c *C) {
14+
r := NewReferenceFromStrings("refs/heads/v4", "6ecf0ef2c2dffb796033e5a02219af86ec6584e5")
15+
c.Assert(r.Type(), Equals, HashReference)
16+
c.Assert(r.Name(), Equals, ExampleReferenceName)
17+
c.Assert(r.Hash(), Equals, NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
18+
19+
r = NewReferenceFromStrings("HEAD", "ref: refs/heads/v4")
20+
c.Assert(r.Type(), Equals, SymbolicReference)
21+
c.Assert(r.Name(), Equals, HEAD)
22+
c.Assert(r.Target(), Equals, ExampleReferenceName)
23+
}
24+
25+
func (s *ReferenceSuite) TestNewSymbolicReference(c *C) {
26+
r := NewSymbolicReference(HEAD, ExampleReferenceName)
27+
c.Assert(r.Type(), Equals, SymbolicReference)
28+
c.Assert(r.Name(), Equals, HEAD)
29+
c.Assert(r.Target(), Equals, ExampleReferenceName)
30+
}
31+
32+
func (s *ReferenceSuite) TestNewHashReference(c *C) {
33+
r := NewHashReference(ExampleReferenceName, NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
34+
c.Assert(r.Type(), Equals, HashReference)
35+
c.Assert(r.Name(), Equals, ExampleReferenceName)
36+
c.Assert(r.Hash(), Equals, NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
37+
}
38+
39+
func (s *ReferenceSuite) TestIsBranch(c *C) {
40+
r := NewHashReference(ExampleReferenceName, ZeroHash)
41+
c.Assert(r.IsBranch(), Equals, true)
42+
}
43+
44+
func (s *ReferenceSuite) TestIsNote(c *C) {
45+
r := NewHashReference(ReferenceName("refs/notes/foo"), ZeroHash)
46+
c.Assert(r.IsNote(), Equals, true)
47+
}
48+
49+
func (s *ReferenceSuite) TestIsRemote(c *C) {
50+
r := NewHashReference(ReferenceName("refs/remotes/origin/master"), ZeroHash)
51+
c.Assert(r.IsRemote(), Equals, true)
52+
}
53+
54+
func (s *ReferenceSuite) TestIsTag(c *C) {
55+
r := NewHashReference(ReferenceName("refs/tags/v3.1."), ZeroHash)
56+
c.Assert(r.IsTag(), Equals, true)
57+
}

0 commit comments

Comments
 (0)