Fast implementation of Git in pure Go
1package object
2
3import (
4 "bytes"
5 "fmt"
6 "strconv"
7
8 "codeberg.org/lindenii/furgit/objectid"
9)
10
11// ParseTree decodes a tree object body.
12func ParseTree(body []byte, algo objectid.Algorithm) (*Tree, error) {
13 var entries []TreeEntry
14
15 i := 0
16 for i < len(body) {
17 space := bytes.IndexByte(body[i:], ' ')
18 if space < 0 {
19 return nil, fmt.Errorf("object: tree: missing mode terminator")
20 }
21
22 modeBytes := body[i : i+space]
23 i += space + 1
24
25 nul := bytes.IndexByte(body[i:], 0)
26 if nul < 0 {
27 return nil, fmt.Errorf("object: tree: missing name terminator")
28 }
29
30 nameBytes := body[i : i+nul]
31 i += nul + 1
32
33 idEnd := i + algo.Size()
34 if idEnd > len(body) {
35 return nil, fmt.Errorf("object: tree: truncated child object id")
36 }
37
38 id, err := objectid.FromBytes(algo, body[i:idEnd])
39 if err != nil {
40 return nil, err
41 }
42
43 i = idEnd
44
45 mode, err := strconv.ParseUint(string(modeBytes), 8, 32)
46 if err != nil {
47 return nil, fmt.Errorf("object: tree: parse mode: %w", err)
48 }
49
50 entries = append(entries, TreeEntry{
51 Mode: FileMode(mode),
52 Name: append([]byte(nil), nameBytes...),
53 ID: id,
54 })
55 }
56
57 return &Tree{Entries: entries}, nil
58}