// Copyright 2014 The Gogs Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package git import ( "sort" "strings" "github.com/Unknwon/com" ) type EntryMode int // There are only a few file modes in Git. They look like unix file modes, but they can only be // one of these. const ( ModeBlob EntryMode = 0100644 ModeExec EntryMode = 0100755 ModeSymlink EntryMode = 0120000 ModeCommit EntryMode = 0160000 ModeTree EntryMode = 0040000 ) type TreeEntry struct { ID sha1 Type ObjectType mode EntryMode name string ptree *Tree commited bool size int64 sized bool } func (te *TreeEntry) Name() string { return te.name } func (te *TreeEntry) Size() int64 { if te.IsDir() { return 0 } if te.sized { return te.size } stdout, _, err := com.ExecCmdDir(te.ptree.repo.Path, "git", "cat-file", "-s", te.ID.String()) if err != nil { return 0 } te.sized = true te.size = com.StrTo(strings.TrimSpace(stdout)).MustInt64() return te.size } func (te *TreeEntry) IsSubModule() bool { return te.mode == ModeCommit } func (te *TreeEntry) IsDir() bool { return te.mode == ModeTree } func (te *TreeEntry) EntryMode() EntryMode { return te.mode } func (te *TreeEntry) Blob() *Blob { return &Blob{ repo: te.ptree.repo, TreeEntry: te, } } type Entries []*TreeEntry var sorter = []func(t1, t2 *TreeEntry) bool{ func(t1, t2 *TreeEntry) bool { return (t1.IsDir() || t1.IsSubModule()) && !t2.IsDir() && !t2.IsSubModule() }, func(t1, t2 *TreeEntry) bool { return t1.name < t2.name }, } func (bs Entries) Len() int { return len(bs) } func (bs Entries) Swap(i, j int) { bs[i], bs[j] = bs[j], bs[i] } func (bs Entries) Less(i, j int) bool { t1, t2 := bs[i], bs[j] var k int for k = 0; k < len(sorter)-1; k++ { sort := sorter[k] switch { case sort(t1, t2): return true case sort(t2, t1): return false } } return sorter[k](t1, t2) } func (bs Entries) Sort() { sort.Sort(bs) }