-
Notifications
You must be signed in to change notification settings - Fork 1
/
loose.go
119 lines (98 loc) · 1.84 KB
/
loose.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package git
import (
"bytes"
"compress/zlib"
"encoding/hex"
"io"
"io/ioutil"
"os"
"path"
)
type GitDir struct {
owner *Git
Dir string
}
func Bare(g *Git, d string) (*GitDir, error) {
bare := &GitDir{owner: g, Dir: d}
g.AddStore(bare)
return bare, nil
}
type LooseObject struct {
repo *GitDir
name Ptr
file string
loaded GitObject
}
func (l *LooseObject) Type() ObjType {
x, err := l.Load()
if err != nil {
return ObjNone
}
return x.Type()
}
func (l *LooseObject) Name() *Ptr {
return &l.name
}
func (l *LooseObject) Payload() ([]byte, error) {
rdr, err := os.Open(l.file)
if err != nil {
return nil, err
}
defer rdr.Close()
rc, err := zlib.NewReader(rdr)
if err != nil {
return nil, err
}
defer rc.Close()
return ioutil.ReadAll(rc)
}
func (l *LooseObject) Load() (GitObject, error) {
if l.loaded != nil {
return l.loaded, nil
}
buf, err := l.Payload()
if err != nil {
return nil, err
}
k := bytes.IndexByte(buf, ' ')
if k < 0 {
return nil, ErrUnknownObjectType
}
z := bytes.IndexByte(buf, 0)
// TODO double-check the hash (assert SHA1(buf) == l.name)
// TODO double-check the length
t := typeFromString[string(buf[:k])]
return l.repo.owner.Interpret(&l.name, t, buf[z+1:])
}
func (g *GitDir) Get(p *Ptr) GitObject {
h := hex.EncodeToString(p.hash[:])
f := path.Join(g.Dir, "objects", h[:2], h[2:])
_, err := os.Stat(f)
if err != nil {
return nil
}
return &LooseObject{
repo: g,
name: *p,
file: f,
}
}
/*func (g *Git) Get(p *Ptr) (io.ReadCloser, error) {
h := hex.EncodeToString(p.hash[:])
f := path.Join(g.Dir, "objects", h[:2], h[2:])
rdr, err := os.Open(f)
if err != nil {
return nil, err
}
rc, err := zlib.NewReader(rdr)
if err != nil {
rdr.Close()
return nil, err
}
return &ObjFile{raw: rdr, unz: rc}, nil
}
*/
type ObjFile struct {
raw *os.File
unz io.ReadCloser
}