repo2.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package models
  5. import (
  6. "path"
  7. "strings"
  8. "time"
  9. git "github.com/gogits/git"
  10. )
  11. type RepoFile struct {
  12. *git.TreeEntry
  13. Path string
  14. Message string
  15. Created time.Time
  16. Size int64
  17. LastCommit string
  18. }
  19. func findTree(repo *git.Repository, tree *git.Tree, rpath string) *git.Tree {
  20. if rpath == "" {
  21. return tree
  22. }
  23. paths := strings.Split(rpath, "/")
  24. var g = tree
  25. for _, p := range paths {
  26. s := g.EntryByName(p)
  27. if s == nil {
  28. return nil
  29. }
  30. g, err := repo.LookupTree(s.Id)
  31. if err != nil {
  32. return nil
  33. }
  34. if g == nil {
  35. return nil
  36. }
  37. }
  38. return g
  39. }
  40. func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, error) {
  41. f := RepoPath(userName, reposName)
  42. repo, err := git.OpenRepository(f)
  43. if err != nil {
  44. return nil, err
  45. }
  46. ref, err := repo.LookupReference("refs/heads/" + branchName)
  47. if err != nil {
  48. return nil, err
  49. }
  50. lastCommit, err := repo.LookupCommit(ref.Oid)
  51. if err != nil {
  52. return nil, err
  53. }
  54. var repodirs []*RepoFile
  55. var repofiles []*RepoFile
  56. lastCommit.Tree.Walk(func(dirname string, entry *git.TreeEntry) int {
  57. if dirname == rpath {
  58. size, err := repo.ObjectSize(entry.Id)
  59. if err != nil {
  60. return 0
  61. }
  62. var cm = lastCommit
  63. for {
  64. if cm.ParentCount() == 0 {
  65. break
  66. } else if cm.ParentCount() == 1 {
  67. pt := findTree(repo, cm.Parent(0).Tree, dirname)
  68. if pt == nil {
  69. break
  70. }
  71. pEntry := pt.EntryByName(entry.Name)
  72. if pEntry == nil || !pEntry.Id.Equal(entry.Id) {
  73. break
  74. } else {
  75. cm = cm.Parent(0)
  76. }
  77. } else {
  78. var emptyCnt = 0
  79. var sameIdcnt = 0
  80. for i := 0; i < cm.ParentCount(); i++ {
  81. p := cm.Parent(i)
  82. pt := findTree(repo, p.Tree, dirname)
  83. var pEntry *git.TreeEntry
  84. if pt != nil {
  85. pEntry = pt.EntryByName(entry.Name)
  86. }
  87. if pEntry == nil {
  88. if emptyCnt == cm.ParentCount()-1 {
  89. goto loop
  90. } else {
  91. emptyCnt = emptyCnt + 1
  92. continue
  93. }
  94. } else {
  95. if !pEntry.Id.Equal(entry.Id) {
  96. goto loop
  97. } else {
  98. if sameIdcnt == cm.ParentCount()-1 {
  99. // TODO: now follow the first parent commit?
  100. cm = cm.Parent(0)
  101. break
  102. }
  103. sameIdcnt = sameIdcnt + 1
  104. }
  105. }
  106. }
  107. }
  108. }
  109. loop:
  110. rp := &RepoFile{
  111. entry,
  112. path.Join(dirname, entry.Name),
  113. cm.Message(),
  114. cm.Committer.When,
  115. size,
  116. cm.Id().String(),
  117. }
  118. if entry.IsFile() {
  119. repofiles = append(repofiles, rp)
  120. } else if entry.IsDir() {
  121. repodirs = append(repodirs, rp)
  122. }
  123. }
  124. return 0
  125. })
  126. return append(repodirs, repofiles...), nil
  127. }