1package bug
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/pkg/errors"
8
9 "github.com/MichaelMure/git-bug/repository"
10 "github.com/MichaelMure/git-bug/util/lamport"
11)
12
13type gitTree struct {
14 opsEntry repository.TreeEntry
15 createTime lamport.Time
16 editTime lamport.Time
17}
18
19func readTree(repo repository.RepoData, hash repository.Hash) (*gitTree, error) {
20 tree := &gitTree{}
21
22 entries, err := repo.ReadTree(hash)
23 if err != nil {
24 return nil, errors.Wrap(err, "can't list git tree entries")
25 }
26
27 opsFound := false
28
29 for _, entry := range entries {
30 if entry.Name == opsEntryName {
31 tree.opsEntry = entry
32 opsFound = true
33 continue
34 }
35 if strings.HasPrefix(entry.Name, createClockEntryPrefix) {
36 n, err := fmt.Sscanf(entry.Name, createClockEntryPattern, &tree.createTime)
37 if err != nil {
38 return nil, errors.Wrap(err, "can't read create lamport time")
39 }
40 if n != 1 {
41 return nil, fmt.Errorf("could not parse create time lamport value")
42 }
43 }
44 if strings.HasPrefix(entry.Name, editClockEntryPrefix) {
45 n, err := fmt.Sscanf(entry.Name, editClockEntryPattern, &tree.editTime)
46 if err != nil {
47 return nil, errors.Wrap(err, "can't read edit lamport time")
48 }
49 if n != 1 {
50 return nil, fmt.Errorf("could not parse edit time lamport value")
51 }
52 }
53 }
54
55 if !opsFound {
56 return nil, errors.New("invalid tree, missing the ops entry")
57 }
58
59 return tree, nil
60}
61
62func makeMediaTree(pack OperationPack) []repository.TreeEntry {
63 var tree []repository.TreeEntry
64 counter := 0
65 added := make(map[repository.Hash]interface{})
66
67 for _, ops := range pack.Operations {
68 for _, file := range ops.GetFiles() {
69 if _, has := added[file]; !has {
70 tree = append(tree, repository.TreeEntry{
71 ObjectType: repository.Blob,
72 Hash: file,
73 // The name is not important here, we only need to
74 // reference the blob.
75 Name: fmt.Sprintf("file%d", counter),
76 })
77 counter++
78 added[file] = struct{}{}
79 }
80 }
81 }
82
83 return tree
84}