diff options
author | Antonio Jesus Navarro Perez <antonio@sourced.tech> | 2017-02-22 15:49:37 +0100 |
---|---|---|
committer | Antonio Jesus Navarro Perez <antonio@sourced.tech> | 2017-02-24 11:08:14 +0100 |
commit | affc06dec90529073b5a3b76291b953232f034d9 (patch) | |
tree | 4300a62bfc3957d51183321254dae3e9d4a314c9 /plumbing/difftree/treenoder.go | |
parent | f93e5712a86b96370673a02fa7ffbe5e0aec0c66 (diff) | |
download | go-git-affc06dec90529073b5a3b76291b953232f034d9.tar.gz |
plumbing/object: move difftree to object package
- To avoid ciclic dependency errors, we move all the difftree files to object package.
- Added Diff method to Tree object.
Diffstat (limited to 'plumbing/difftree/treenoder.go')
-rw-r--r-- | plumbing/difftree/treenoder.go | 141 |
1 files changed, 0 insertions, 141 deletions
diff --git a/plumbing/difftree/treenoder.go b/plumbing/difftree/treenoder.go deleted file mode 100644 index c0ed948..0000000 --- a/plumbing/difftree/treenoder.go +++ /dev/null @@ -1,141 +0,0 @@ -package difftree - -// A treenoder is a helper type that wraps git trees into merkletrie -// noders. -// -// As a merkletrie noder doesn't understand the concept of modes (e.g. -// file permissions), the treenoder includes the mode of the git tree in -// the hash, so changes in the modes will be detected as modifications -// to the file contents by the merkletrie difftree algorithm. This is -// consistent with how the "git diff-tree" command works. -import ( - "encoding/binary" - "io" - "os" - - "srcd.works/go-git.v4/plumbing" - "srcd.works/go-git.v4/plumbing/object" - "srcd.works/go-git.v4/utils/merkletrie/noder" -) - -type treeNoder struct { - parent *object.Tree // the root node is its own parent - name string // empty string for the root node - mode os.FileMode - hash plumbing.Hash - children []noder.Noder // memoized -} - -func newTreeNoder(t *object.Tree) *treeNoder { - if t == nil { - return &treeNoder{} - } - - return &treeNoder{ - parent: t, - name: "", - mode: os.ModeDir, - hash: t.Hash, - } -} - -func (t *treeNoder) isRoot() bool { - return t.name == "" -} - -func (t *treeNoder) String() string { - return "treeNoder <" + t.name + ">" -} - -func (t *treeNoder) Hash() []byte { - return append(t.hash[:], modeToBytes(t.mode)...) -} - -// mode in little endian (endianess is an arbitrary decission). -func modeToBytes(m os.FileMode) []byte { - ret := make([]byte, 4) - binary.LittleEndian.PutUint32(ret, uint32(m)) - return ret -} - -func (t *treeNoder) Name() string { - return t.name -} - -func (t *treeNoder) IsDir() bool { - return t.mode.IsDir() -} - -// Children will return the children of a treenoder as treenoders, -// building them from the children of the wrapped git tree. -func (t *treeNoder) Children() ([]noder.Noder, error) { - if !t.mode.IsDir() { - return noder.NoChildren, nil - } - - // children are memoized for efficiency - if t.children != nil { - return t.children, nil - } - - // the parent of the returned children will be ourself as a tree if - // we are a not the root treenoder. The root is special as it - // is is own parent. - parent := t.parent - if !t.isRoot() { - var err error - if parent, err = t.parent.Tree(t.name); err != nil { - return nil, err - } - } - - return transformChildren(parent) -} - -// Returns the children of a tree as treenoders. -// Efficiency is key here. -func transformChildren(t *object.Tree) ([]noder.Noder, error) { - var err error - var e object.TreeEntry - - // there will be more tree entries than children in the tree, - // due to submodules and empty directories, but I think it is still - // worth it to pre-allocate the whole array now, even if sometimes - // is bigger than needed. - ret := make([]noder.Noder, 0, len(t.Entries)) - - walker := object.NewTreeWalker(t, false) // don't recurse - // don't defer walker.Close() for efficiency reasons. - for { - _, e, err = walker.Next() - if err == io.EOF { - break - } - if err != nil { - walker.Close() - return nil, err - } - - ret = append(ret, &treeNoder{ - parent: t, - name: e.Name, - mode: e.Mode, - hash: e.Hash, - }) - } - walker.Close() - - return ret, nil -} - -// len(t.tree.Entries) != the number of elements walked by treewalker -// for some reason because of empty directories, submodules, etc, so we -// have to walk here. -func (t *treeNoder) NumChildren() (int, error) { - children, err := t.Children() - if err != nil { - return 0, err - } - - return len(children), nil -} |