You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tree_nogogit.go 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright 2020 The Gitea 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. //go:build !gogit
  5. // +build !gogit
  6. package git
  7. import (
  8. "io"
  9. "math"
  10. "strings"
  11. )
  12. // Tree represents a flat directory listing.
  13. type Tree struct {
  14. ID SHA1
  15. ResolvedID SHA1
  16. repo *Repository
  17. // parent tree
  18. ptree *Tree
  19. entries Entries
  20. entriesParsed bool
  21. entriesRecursive Entries
  22. entriesRecursiveParsed bool
  23. }
  24. // ListEntries returns all entries of current tree.
  25. func (t *Tree) ListEntries() (Entries, error) {
  26. if t.entriesParsed {
  27. return t.entries, nil
  28. }
  29. if t.repo != nil {
  30. wr, rd, cancel := t.repo.CatFileBatch()
  31. defer cancel()
  32. _, _ = wr.Write([]byte(t.ID.String() + "\n"))
  33. _, typ, sz, err := ReadBatchLine(rd)
  34. if err != nil {
  35. return nil, err
  36. }
  37. if typ == "commit" {
  38. treeID, err := ReadTreeID(rd, sz)
  39. if err != nil && err != io.EOF {
  40. return nil, err
  41. }
  42. _, _ = wr.Write([]byte(treeID + "\n"))
  43. _, typ, sz, err = ReadBatchLine(rd)
  44. if err != nil {
  45. return nil, err
  46. }
  47. }
  48. if typ == "tree" {
  49. t.entries, err = catBatchParseTreeEntries(t, rd, sz)
  50. if err != nil {
  51. return nil, err
  52. }
  53. t.entriesParsed = true
  54. return t.entries, nil
  55. }
  56. // Not a tree just use ls-tree instead
  57. for sz > math.MaxInt32 {
  58. discarded, err := rd.Discard(math.MaxInt32)
  59. sz -= int64(discarded)
  60. if err != nil {
  61. return nil, err
  62. }
  63. }
  64. for sz > 0 {
  65. discarded, err := rd.Discard(int(sz))
  66. sz -= int64(discarded)
  67. if err != nil {
  68. return nil, err
  69. }
  70. }
  71. }
  72. stdout, err := NewCommand("ls-tree", "-l", t.ID.String()).RunInDirBytes(t.repo.Path)
  73. if err != nil {
  74. if strings.Contains(err.Error(), "fatal: Not a valid object name") || strings.Contains(err.Error(), "fatal: not a tree object") {
  75. return nil, ErrNotExist{
  76. ID: t.ID.String(),
  77. }
  78. }
  79. return nil, err
  80. }
  81. t.entries, err = parseTreeEntries(stdout, t)
  82. if err == nil {
  83. t.entriesParsed = true
  84. }
  85. return t.entries, err
  86. }
  87. // ListEntriesRecursive returns all entries of current tree recursively including all subtrees
  88. func (t *Tree) ListEntriesRecursive() (Entries, error) {
  89. if t.entriesRecursiveParsed {
  90. return t.entriesRecursive, nil
  91. }
  92. stdout, err := NewCommand("ls-tree", "-t", "-l", "-r", t.ID.String()).RunInDirBytes(t.repo.Path)
  93. if err != nil {
  94. return nil, err
  95. }
  96. t.entriesRecursive, err = parseTreeEntries(stdout, t)
  97. if err == nil {
  98. t.entriesRecursiveParsed = true
  99. }
  100. return t.entriesRecursive, err
  101. }