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