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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
package index
import (
"bytes"
"path/filepath"
"strings"
"gopkg.in/src-d/go-git.v4/plumbing/format/index"
"gopkg.in/src-d/go-git.v4/utils/merkletrie/noder"
)
func IsEquals(a, b noder.Hasher) bool {
pathA := a.(noder.Path)
pathB := b.(noder.Path)
if pathA[len(pathA)-1].IsDir() || pathB[len(pathB)-1].IsDir() {
return false
}
return bytes.Equal(a.Hash(), b.Hash())
}
type Node struct {
index *index.Index
parent string
name string
entry index.Entry
isDir bool
}
func NewRootNode(idx *index.Index) (*Node, error) {
return &Node{index: idx, isDir: true}, nil
}
func (n *Node) String() string {
return n.fullpath()
}
func (n *Node) Hash() []byte {
if n.IsDir() {
return nil
}
return append(n.entry.Hash[:], n.entry.Mode.Bytes()...)
}
func (n *Node) Name() string {
return n.name
}
func (n *Node) IsDir() bool {
return n.isDir
}
func (n *Node) Children() ([]noder.Noder, error) {
path := n.fullpath()
dirs := make(map[string]bool)
var c []noder.Noder
for _, e := range n.index.Entries {
if e.Name == path {
continue
}
prefix := path
if prefix != "" {
prefix += "/"
}
if !strings.HasPrefix(e.Name, prefix) {
continue
}
name := e.Name[len(path):]
if len(name) != 0 && name[0] == '/' {
name = name[1:]
}
parts := strings.Split(name, "/")
if len(parts) > 1 {
dirs[parts[0]] = true
continue
}
c = append(c, &Node{
index: n.index,
parent: path,
name: name,
entry: e,
})
}
for dir := range dirs {
c = append(c, &Node{
index: n.index,
parent: path,
name: dir,
isDir: true,
})
}
return c, nil
}
func (n *Node) NumChildren() (int, error) {
files, err := n.Children()
return len(files), err
}
func (n *Node) fullpath() string {
return filepath.Join(n.parent, n.name)
}
|