91 lines
2 KiB
Go
91 lines
2 KiB
Go
|
package index
|
||
|
|
||
|
import (
|
||
|
"path"
|
||
|
"strings"
|
||
|
|
||
|
"gopkg.in/src-d/go-git.v4/plumbing/format/index"
|
||
|
"gopkg.in/src-d/go-git.v4/utils/merkletrie/noder"
|
||
|
)
|
||
|
|
||
|
// The node represents a index.Entry or a directory inferred from the path
|
||
|
// of all entries. It implements the interface noder.Noder of merkletrie
|
||
|
// package.
|
||
|
//
|
||
|
// This implementation implements a "standard" hash method being able to be
|
||
|
// compared with any other noder.Noder implementation inside of go-git
|
||
|
type node struct {
|
||
|
path string
|
||
|
entry *index.Entry
|
||
|
children []noder.Noder
|
||
|
isDir bool
|
||
|
}
|
||
|
|
||
|
// NewRootNode returns the root node of a computed tree from a index.Index,
|
||
|
func NewRootNode(idx *index.Index) noder.Noder {
|
||
|
const rootNode = ""
|
||
|
|
||
|
m := map[string]*node{rootNode: {isDir: true}}
|
||
|
|
||
|
for _, e := range idx.Entries {
|
||
|
parts := strings.Split(e.Name, string("/"))
|
||
|
|
||
|
var fullpath string
|
||
|
for _, part := range parts {
|
||
|
parent := fullpath
|
||
|
fullpath = path.Join(fullpath, part)
|
||
|
|
||
|
if _, ok := m[fullpath]; ok {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
n := &node{path: fullpath}
|
||
|
if fullpath == e.Name {
|
||
|
n.entry = e
|
||
|
} else {
|
||
|
n.isDir = true
|
||
|
}
|
||
|
|
||
|
m[n.path] = n
|
||
|
m[parent].children = append(m[parent].children, n)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return m[rootNode]
|
||
|
}
|
||
|
|
||
|
func (n *node) String() string {
|
||
|
return n.path
|
||
|
}
|
||
|
|
||
|
// Hash the hash of a filesystem is a 24-byte slice, is the result of
|
||
|
// concatenating the computed plumbing.Hash of the file as a Blob and its
|
||
|
// plumbing.FileMode; that way the difftree algorithm will detect changes in the
|
||
|
// contents of files and also in their mode.
|
||
|
//
|
||
|
// If the node is computed and not based on a index.Entry the hash is equals
|
||
|
// to a 24-bytes slices of zero values.
|
||
|
func (n *node) Hash() []byte {
|
||
|
if n.entry == nil {
|
||
|
return make([]byte, 24)
|
||
|
}
|
||
|
|
||
|
return append(n.entry.Hash[:], n.entry.Mode.Bytes()...)
|
||
|
}
|
||
|
|
||
|
func (n *node) Name() string {
|
||
|
return path.Base(n.path)
|
||
|
}
|
||
|
|
||
|
func (n *node) IsDir() bool {
|
||
|
return n.isDir
|
||
|
}
|
||
|
|
||
|
func (n *node) Children() ([]noder.Noder, error) {
|
||
|
return n.children, nil
|
||
|
}
|
||
|
|
||
|
func (n *node) NumChildren() (int, error) {
|
||
|
return len(n.children), nil
|
||
|
}
|