Fast implementation of Git in pure Go
1package object
2
3import (
4 "bytes"
5 "errors"
6 "fmt"
7
8 "codeberg.org/lindenii/furgit/objectheader"
9 "codeberg.org/lindenii/furgit/objecttype"
10)
11
12// SerializeWithoutHeader renders the raw commit body bytes.
13func (commit *Commit) SerializeWithoutHeader() ([]byte, error) {
14 var buf bytes.Buffer
15
16 if commit.Tree.Size() == 0 {
17 return nil, errors.New("object: commit: missing tree id")
18 }
19
20 fmt.Fprintf(&buf, "tree %s\n", commit.Tree.String())
21
22 for _, parent := range commit.Parents {
23 fmt.Fprintf(&buf, "parent %s\n", parent.String())
24 }
25
26 authorBytes, err := commit.Author.Serialize()
27 if err != nil {
28 return nil, err
29 }
30
31 buf.WriteString("author ")
32 buf.Write(authorBytes)
33 buf.WriteByte('\n')
34
35 committerBytes, err := commit.Committer.Serialize()
36 if err != nil {
37 return nil, err
38 }
39
40 buf.WriteString("committer ")
41 buf.Write(committerBytes)
42 buf.WriteByte('\n')
43
44 if commit.ChangeID != "" {
45 buf.WriteString("change-id ")
46 buf.WriteString(commit.ChangeID)
47 buf.WriteByte('\n')
48 }
49
50 for _, h := range commit.ExtraHeaders {
51 if h.Key == "" {
52 return nil, errors.New("object: commit: extra header has empty key")
53 }
54
55 buf.WriteString(h.Key)
56 buf.WriteByte(' ')
57 buf.Write(h.Value)
58 buf.WriteByte('\n')
59 }
60
61 buf.WriteByte('\n')
62 buf.Write(commit.Message)
63
64 return buf.Bytes(), nil
65}
66
67// SerializeWithHeader renders the raw object (header + body).
68func (commit *Commit) SerializeWithHeader() ([]byte, error) {
69 body, err := commit.SerializeWithoutHeader()
70 if err != nil {
71 return nil, err
72 }
73
74 header, ok := objectheader.Encode(objecttype.TypeCommit, int64(len(body)))
75 if !ok {
76 return nil, errors.New("object: commit: failed to encode object header")
77 }
78
79 raw := make([]byte, len(header)+len(body))
80 copy(raw, header)
81 copy(raw[len(header):], body)
82
83 return raw, nil
84}