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.

repo_index.go 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package git
  4. import (
  5. "bytes"
  6. "context"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "code.gitea.io/gitea/modules/log"
  11. "code.gitea.io/gitea/modules/util"
  12. )
  13. // ReadTreeToIndex reads a treeish to the index
  14. func (repo *Repository) ReadTreeToIndex(treeish string, indexFilename ...string) error {
  15. if len(treeish) != SHAFullLength {
  16. res, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(treeish).RunStdString(&RunOpts{Dir: repo.Path})
  17. if err != nil {
  18. return err
  19. }
  20. if len(res) > 0 {
  21. treeish = res[:len(res)-1]
  22. }
  23. }
  24. id, err := NewIDFromString(treeish)
  25. if err != nil {
  26. return err
  27. }
  28. return repo.readTreeToIndex(id, indexFilename...)
  29. }
  30. func (repo *Repository) readTreeToIndex(id SHA1, indexFilename ...string) error {
  31. var env []string
  32. if len(indexFilename) > 0 {
  33. env = append(os.Environ(), "GIT_INDEX_FILE="+indexFilename[0])
  34. }
  35. _, _, err := NewCommand(repo.Ctx, "read-tree").AddDynamicArguments(id.String()).RunStdString(&RunOpts{Dir: repo.Path, Env: env})
  36. if err != nil {
  37. return err
  38. }
  39. return nil
  40. }
  41. // ReadTreeToTemporaryIndex reads a treeish to a temporary index file
  42. func (repo *Repository) ReadTreeToTemporaryIndex(treeish string) (filename, tmpDir string, cancel context.CancelFunc, err error) {
  43. tmpDir, err = os.MkdirTemp("", "index")
  44. if err != nil {
  45. return
  46. }
  47. filename = filepath.Join(tmpDir, ".tmp-index")
  48. cancel = func() {
  49. err := util.RemoveAll(tmpDir)
  50. if err != nil {
  51. log.Error("failed to remove tmp index file: %v", err)
  52. }
  53. }
  54. err = repo.ReadTreeToIndex(treeish, filename)
  55. if err != nil {
  56. defer cancel()
  57. return "", "", func() {}, err
  58. }
  59. return filename, tmpDir, cancel, err
  60. }
  61. // EmptyIndex empties the index
  62. func (repo *Repository) EmptyIndex() error {
  63. _, _, err := NewCommand(repo.Ctx, "read-tree", "--empty").RunStdString(&RunOpts{Dir: repo.Path})
  64. return err
  65. }
  66. // LsFiles checks if the given filenames are in the index
  67. func (repo *Repository) LsFiles(filenames ...string) ([]string, error) {
  68. cmd := NewCommand(repo.Ctx, "ls-files", "-z").AddDashesAndList(filenames...)
  69. res, _, err := cmd.RunStdBytes(&RunOpts{Dir: repo.Path})
  70. if err != nil {
  71. return nil, err
  72. }
  73. filelist := make([]string, 0, len(filenames))
  74. for _, line := range bytes.Split(res, []byte{'\000'}) {
  75. filelist = append(filelist, string(line))
  76. }
  77. return filelist, err
  78. }
  79. // RemoveFilesFromIndex removes given filenames from the index - it does not check whether they are present.
  80. func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error {
  81. cmd := NewCommand(repo.Ctx, "update-index", "--remove", "-z", "--index-info")
  82. stdout := new(bytes.Buffer)
  83. stderr := new(bytes.Buffer)
  84. buffer := new(bytes.Buffer)
  85. for _, file := range filenames {
  86. if file != "" {
  87. buffer.WriteString("0 0000000000000000000000000000000000000000\t")
  88. buffer.WriteString(file)
  89. buffer.WriteByte('\000')
  90. }
  91. }
  92. return cmd.Run(&RunOpts{
  93. Dir: repo.Path,
  94. Stdin: bytes.NewReader(buffer.Bytes()),
  95. Stdout: stdout,
  96. Stderr: stderr,
  97. })
  98. }
  99. // AddObjectToIndex adds the provided object hash to the index at the provided filename
  100. func (repo *Repository) AddObjectToIndex(mode string, object SHA1, filename string) error {
  101. cmd := NewCommand(repo.Ctx, "update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments(mode, object.String(), filename)
  102. _, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path})
  103. return err
  104. }
  105. // WriteTree writes the current index as a tree to the object db and returns its hash
  106. func (repo *Repository) WriteTree() (*Tree, error) {
  107. stdout, _, runErr := NewCommand(repo.Ctx, "write-tree").RunStdString(&RunOpts{Dir: repo.Path})
  108. if runErr != nil {
  109. return nil, runErr
  110. }
  111. id, err := NewIDFromString(strings.TrimSpace(stdout))
  112. if err != nil {
  113. return nil, err
  114. }
  115. return NewTree(repo, id), nil
  116. }