MCPcopy Index your code
hub / github.com/gogs/gogs / UpdateRepoFile

Method UpdateRepoFile

internal/database/repo_editor.go:143–243  ·  view source on GitHub ↗

UpdateRepoFile adds or updates a file in repository.

(doer *User, opts UpdateRepoFileOptions)

Source from the content-addressed store, hash-verified

141
142// UpdateRepoFile adds or updates a file in repository.
143func (r *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) error {
144 // 🚨 SECURITY: Prevent uploading files into the ".git" directory.
145 if isRepositoryGitPath(opts.NewTreeName) {
146 return errors.Errorf("bad tree path %q", opts.NewTreeName)
147 }
148
149 repoWorkingPool.CheckIn(com.ToStr(r.ID))
150 defer repoWorkingPool.CheckOut(com.ToStr(r.ID))
151
152 if err := r.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil {
153 return errors.Newf("discard local repo branch[%s] changes: %v", opts.OldBranch, err)
154 } else if err = r.UpdateLocalCopyBranch(opts.OldBranch); err != nil {
155 return errors.Newf("update local copy branch[%s]: %v", opts.OldBranch, err)
156 }
157
158 localPath := r.LocalCopyPath()
159
160 // 🚨 SECURITY: Prevent touching files in surprising places, reject operations
161 // that involve symlinks.
162 if hasSymlinkInPath(localPath, opts.OldTreeName) || hasSymlinkInPath(localPath, opts.NewTreeName) {
163 return errors.New("cannot update file with symbolic link in path")
164 }
165
166 repoPath := r.RepoPath()
167 if opts.OldBranch != opts.NewBranch {
168 // Directly return error if new branch already exists in the server
169 if git.RepoHasBranch(repoPath, opts.NewBranch) {
170 return BranchAlreadyExists{Name: opts.NewBranch}
171 }
172
173 // Otherwise, delete branch from local copy in case out of sync
174 if git.RepoHasBranch(localPath, opts.NewBranch) {
175 if err := git.DeleteBranch(localPath, opts.NewBranch, git.DeleteBranchOptions{
176 Force: true,
177 }); err != nil {
178 return errors.Newf("delete branch %q: %v", opts.NewBranch, err)
179 }
180 }
181
182 if err := r.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil {
183 return errors.Newf("checkout new branch[%s] from old branch[%s]: %v", opts.NewBranch, opts.OldBranch, err)
184 }
185 }
186
187 oldFilePath := path.Join(localPath, opts.OldTreeName)
188 newFilePath := path.Join(localPath, opts.NewTreeName)
189
190 // Prompt the user if the meant-to-be new file already exists.
191 if osutil.Exist(newFilePath) && opts.IsNewFile {
192 return ErrRepoFileAlreadyExist{newFilePath}
193 }
194
195 if err := os.MkdirAll(path.Dir(newFilePath), os.ModePerm); err != nil {
196 return errors.Wrapf(err, "create parent directories of %q", newFilePath)
197 }
198
199 if osutil.IsFile(oldFilePath) && opts.OldTreeName != opts.NewTreeName {
200 if err := git.Move(localPath, opts.OldTreeName, opts.NewTreeName); err != nil {

Callers 2

editFilePostFunction · 0.80
PutContentsFunction · 0.80

Implementers 2

Repositoryinternal/database/repo.go
mailerRepointernal/database/issue_mail.go

Calls 15

UpdateLocalCopyBranchMethod · 0.95
LocalCopyPathMethod · 0.95
RepoPathMethod · 0.95
CheckoutNewBranchMethod · 0.95
MustOwnerMethod · 0.95
ExistFunction · 0.92
IsFileFunction · 0.92
isRepositoryGitPathFunction · 0.85
hasSymlinkInPathFunction · 0.85
ComposeHookEnvsFunction · 0.85
CheckInMethod · 0.80

Tested by

no test coverage detected