@@ -0,0 +1,72 @@
+package repository
+
+import (
+ "fmt"
+ "github.com/MichaelMure/git-bug/util"
+ "github.com/pkg/errors"
+ "strings"
+)
+
+type TreeEntry struct {
+ ObjectType ObjectType
+ Hash util.Hash
+ Name string
+}
+
+type ObjectType int
+
+const (
+ Unknown ObjectType = iota
+ Blob
+ Tree
+)
+
+func ParseTreeEntry(line string) (TreeEntry, error) {
+ fields := strings.Fields(line)
+
+ if len(fields) < 4 {
+ return TreeEntry{}, errors.New("Invalid input to parse as a TreeEntry")
+ }
+
+ objType, err := ParseObjectType(fields[0], fields[1])
+
+ if err != nil {
+ return TreeEntry{}, err
+ }
+
+ hash := util.Hash(fields[2])
+ name := strings.Join(fields[3:], "")
+
+ return TreeEntry{
+ ObjectType: objType,
+ Hash: hash,
+ Name: name,
+ }, nil
+}
+
+// Format the entry as a git ls-tree compatible line
+func (entry TreeEntry) Format() string {
+ return fmt.Sprintf("%s %s\t%s\n", entry.ObjectType.Format(), entry.Hash, entry.Name)
+}
+
+func (ot ObjectType) Format() string {
+ switch ot {
+ case Blob:
+ return "100644 blob"
+ case Tree:
+ return "040000 tree"
+ default:
+ panic("Unknown git object type")
+ }
+}
+
+func ParseObjectType(mode, objType string) (ObjectType, error) {
+ switch {
+ case mode == "100644" && objType == "blob":
+ return Blob, nil
+ case mode == "040000" && objType == "tree":
+ return Tree, nil
+ default:
+ return Unknown, errors.Errorf("Unknown git object type %s %s", mode, objType)
+ }
+}
@@ -0,0 +1,34 @@
+package repository
+
+import (
+ "github.com/MichaelMure/git-bug/util"
+ "testing"
+)
+
+func TestTreeEntryFormat(t *testing.T) {
+
+ entries := []TreeEntry{
+ {Blob, util.Hash("a85730cf5287d40a1e32d3a671ba2296c73387cb"), "name"},
+ {Tree, util.Hash("a85730cf5287d40a1e32d3a671ba2296c73387cb"), "name"},
+ }
+
+ for _, entry := range entries {
+ _ = entry.Format()
+ }
+}
+
+func TestTreeEntryParse(t *testing.T) {
+ lines := []string{
+ "100644 blob 1e5ffaffc67049635ba7b01f77143313503f1ca1 .gitignore",
+ "040000 tree 728421fea4168b874bc1a8aa409d6723ef445a4e bug",
+ }
+
+ for _, line := range lines {
+ _, err := ParseTreeEntry(line)
+
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+}