/
blob.go
110 lines (96 loc) · 2.47 KB
/
blob.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
package git4go
import (
"errors"
"io/ioutil"
"os"
"path/filepath"
)
func (r *Repository) LookupBlob(oid *Oid) (*Blob, error) {
obj, err := objectLookupPrefix(r, oid, GitOidHexSize, ObjectBlob)
return obj.(*Blob), err
}
func (r *Repository) LookupPrefixBlob(oid *Oid, length int) (*Blob, error) {
obj, err := objectLookupPrefix(r, oid, length, ObjectBlob)
return obj.(*Blob), err
}
func (r *Repository) CreateBlobFromBuffer(data []byte) (*Oid, error) {
odb, err := r.Odb()
if err != nil {
return nil, err
}
return odb.Write(data, ObjectBlob)
}
func (r *Repository) CreateBlobFromWorkdir(path string) (*Oid, error) {
oid, _, err := createBlobCreateFromPaths(r, "", path, 0, true)
return oid, err
}
type BlobChunkCallback func(maxLen int) ([]byte, error)
// todo
func (r *Repository) CreateBlobFromChunks(hintPath string, callback BlobChunkCallback) (*Oid, error) {
return nil, nil
}
type Blob struct {
gitObject
contents []byte
}
func (b *Blob) Type() ObjectType {
return ObjectBlob
}
func (b *Blob) Peel(targetType ObjectType) (Object, error) {
return peel(b, targetType)
}
func (b *Blob) Size() int64 {
return int64(len(b.contents))
}
func (b *Blob) Contents() []byte {
return b.contents
}
func newBlob(repo *Repository, oid *Oid, contents []byte) *Blob {
return &Blob{
contents: contents,
gitObject: gitObject{
repo: repo,
oid: oid,
},
}
}
func createBlobCreateFromPaths(repo *Repository, contentPath, hintPath string, hintMode Filemode, tryLoadFilters bool) (*Oid, os.FileInfo, error) {
if hintPath == "" && tryLoadFilters {
return nil, nil, errors.New("Assertion error")
}
if contentPath == "" {
if repo.IsBare() {
return nil, nil, MakeGitError("Repository should not be bare", ErrBareRepository)
}
contentPath = filepath.Join(repo.Workdir(), hintPath)
}
stat, err := os.Lstat(contentPath)
if err != nil {
return nil, nil, err
}
if stat.IsDir() {
return nil, nil, MakeGitError("Content path should not be dir", ErrDirectory)
}
if _, err := repo.Odb(); err != nil {
return nil, nil, err
}
var oid *Oid
if stat.Mode()&os.ModeSymlink == os.ModeSymlink {
targetPath, err := os.Readlink(contentPath)
if err != nil {
return nil, nil, err
}
oid, err = repo.CreateBlobFromBuffer([]byte(targetPath))
} else {
// todo: filter
content, err := ioutil.ReadFile(contentPath)
if err != nil {
return nil, nil, err
}
oid, err = repo.CreateBlobFromBuffer(content)
}
if err != nil {
return nil, nil, err
}
return oid, stat, nil
}