diff --git a/models/repo2.go b/models/repo2.go index e3fdc2784b8..ccdda5bdb31 100644 --- a/models/repo2.go +++ b/models/repo2.go @@ -6,6 +6,7 @@ package models import ( "path" + "strings" "time" git "github.com/gogits/git" @@ -13,10 +14,33 @@ import ( type RepoFile struct { *git.TreeEntry - Path string - Message string - Created time.Time - Size int64 + Path string + Message string + Created time.Time + Size int64 + LastCommit string +} + +func findTree(repo *git.Repository, tree *git.Tree, rpath string) *git.Tree { + if rpath == "" { + return tree + } + paths := strings.Split(rpath, "/") + var g = tree + for _, p := range paths { + s := g.EntryByName(p) + if s == nil { + return nil + } + g, err := repo.LookupTree(s.Id) + if err != nil { + return nil + } + if g == nil { + return nil + } + } + return g } func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, error) { @@ -45,23 +69,72 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, if err != nil { return 0 } - switch entry.Filemode { - case git.FileModeBlob, git.FileModeBlobExec: - repofiles = append(repofiles, &RepoFile{ - entry, - path.Join(dirname, entry.Name), - lastCommit.Message(), - lastCommit.Committer.When, - size, - }) - case git.FileModeTree: - repodirs = append(repodirs, &RepoFile{ - entry, - path.Join(dirname, entry.Name), - lastCommit.Message(), - lastCommit.Committer.When, - size, - }) + + var cm = lastCommit + + for { + if cm.ParentCount() == 0 { + break + } else if cm.ParentCount() == 1 { + pt := findTree(repo, cm.Parent(0).Tree, dirname) + if pt == nil { + break + } + pEntry := pt.EntryByName(entry.Name) + if pEntry == nil || !pEntry.Id.Equal(entry.Id) { + break + } else { + cm = cm.Parent(0) + } + } else { + var emptyCnt = 0 + var sameIdcnt = 0 + for i := 0; i < cm.ParentCount(); i++ { + p := cm.Parent(i) + pt := findTree(repo, p.Tree, dirname) + var pEntry *git.TreeEntry + if pt != nil { + pEntry = pt.EntryByName(entry.Name) + } + + if pEntry == nil { + if emptyCnt == cm.ParentCount()-1 { + goto loop + } else { + emptyCnt = emptyCnt + 1 + continue + } + } else { + if !pEntry.Id.Equal(entry.Id) { + goto loop + } else { + if sameIdcnt == cm.ParentCount()-1 { + // TODO: now follow the first parent commit? + cm = cm.Parent(0) + break + } + sameIdcnt = sameIdcnt + 1 + } + } + } + } + } + + loop: + + rp := &RepoFile{ + entry, + path.Join(dirname, entry.Name), + cm.Message(), + cm.Committer.When, + size, + cm.Id().String(), + } + + if entry.IsFile() { + repofiles = append(repofiles, rp) + } else if entry.IsDir() { + repodirs = append(repodirs, rp) } } return 0