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
|
package catfile
import (
"bufio"
"fmt"
"strconv"
"strings"
"gitlab.com/gitlab-org/gitaly/internal/git"
)
// ObjectInfo represents a header returned by `git cat-file --batch`
type ObjectInfo struct {
Oid git.ObjectID
Type string
Size int64
}
// NotFoundError is returned when requesting an object that does not exist.
type NotFoundError struct{ error }
// IsNotFound tests whether err has type NotFoundError.
func IsNotFound(err error) bool {
_, ok := err.(NotFoundError)
return ok
}
// IsBlob returns true if object type is "blob"
func (o *ObjectInfo) IsBlob() bool {
return o.Type == "blob"
}
// ParseObjectInfo reads from a reader and parses the data into an ObjectInfo struct
func ParseObjectInfo(stdout *bufio.Reader) (*ObjectInfo, error) {
infoLine, err := stdout.ReadString('\n')
if err != nil {
return nil, fmt.Errorf("read info line: %w", err)
}
infoLine = strings.TrimSuffix(infoLine, "\n")
if strings.HasSuffix(infoLine, " missing") {
return nil, NotFoundError{fmt.Errorf("object not found")}
}
info := strings.Split(infoLine, " ")
if len(info) != 3 {
return nil, fmt.Errorf("invalid info line: %q", infoLine)
}
oid, err := git.NewObjectIDFromHex(info[0])
if err != nil {
return nil, fmt.Errorf("parse object ID: %w", err)
}
objectSize, err := strconv.ParseInt(info[2], 10, 64)
if err != nil {
return nil, fmt.Errorf("parse object size: %w", err)
}
return &ObjectInfo{
Oid: oid,
Type: info[1],
Size: objectSize,
}, nil
}
|