Repository: gogs/gogs
File: internal/database/repo_editor.go (Go)

Code before:
	NewTreeName string
	Message     string
	Content     string
	IsNewFile   bool
}

// UpdateRepoFile adds or updates a file in repository.
func (r *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) error {
	// 🚨 SECURITY: Prevent uploading files into the ".git" directory.
	if isRepositoryGitPath(opts.NewTreeName) {
		return errors.Errorf("bad tree path %q", opts.NewTreeName)
	}

	repoWorkingPool.CheckIn(com.ToStr(r.ID))
	defer repoWorkingPool.CheckOut(com.ToStr(r.ID))

	if err := r.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil {
		return fmt.Errorf("discard local repo branch[%s] changes: %v", opts.OldBranch, err)
	} else if err = r.UpdateLocalCopyBranch(opts.OldBranch); err != nil {
		return fmt.Errorf("update local copy branch[%s]: %v", opts.OldBranch, err)
	}

	localPath := r.LocalCopyPath()

	// 🚨 SECURITY: Prevent touching files in surprising places, reject operations
	// involves symlinks.
	if hasSymlinkInPath(localPath, opts.OldTreeName) || hasSymlinkInPath(localPath, opts.NewTreeName) {
		return errors.New("cannot update file with symbolic link in path")
	}

	repoPath := r.RepoPath()
	if opts.OldBranch != opts.NewBranch {
		// Directly return error if new branch already exists in the server
		if git.RepoHasBranch(repoPath, opts.NewBranch) {
			return dberrors.BranchAlreadyExists{Name: opts.NewBranch}
		}

		// Otherwise, delete branch from local copy in case out of sync
		if git.RepoHasBranch(localPath, opts.NewBranch) {
			if err := git.DeleteBranch(localPath, opts.NewBranch, git.DeleteBranchOptions{
				Force: true,
			}); err != nil {
				return fmt.Errorf("delete branch %q: %v", opts.NewBranch, err)
			}
		}

		if err := r.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil {
			return fmt.Errorf("checkout new branch[%s] from old branch[%s]: %v", opts.NewBranch, opts.OldBranch, err)
		}
	}


Review comment (suggestion):
Grammar error in comment: "reject operations involves symlinks" should be "reject operations that involve symlinks" or "reject operations involving symlinks".
```suggestion
	// that involve symlinks.
```

Code after:
	NewTreeName string
	Message     string
	Content     string
	IsNewFile   bool
}

// UpdateRepoFile adds or updates a file in repository.
func (r *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) error {
	// 🚨 SECURITY: Prevent uploading files into the ".git" directory.
	if isRepositoryGitPath(opts.NewTreeName) {
		return errors.Errorf("bad tree path %q", opts.NewTreeName)
	}

	repoWorkingPool.CheckIn(com.ToStr(r.ID))
	defer repoWorkingPool.CheckOut(com.ToStr(r.ID))

	if err := r.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil {
		return fmt.Errorf("discard local repo branch[%s] changes: %v", opts.OldBranch, err)
	} else if err = r.UpdateLocalCopyBranch(opts.OldBranch); err != nil {
		return fmt.Errorf("update local copy branch[%s]: %v", opts.OldBranch, err)
	}

	localPath := r.LocalCopyPath()

	// 🚨 SECURITY: Prevent touching files in surprising places, reject operations
	// that involve symlinks.
	if hasSymlinkInPath(localPath, opts.OldTreeName) || hasSymlinkInPath(localPath, opts.NewTreeName) {
		return errors.New("cannot update file with symbolic link in path")
	}

	repoPath := r.RepoPath()
	if opts.OldBranch != opts.NewBranch {
		// Directly return error if new branch already exists in the server
		if git.RepoHasBranch(repoPath, opts.NewBranch) {
			return dberrors.BranchAlreadyExists{Name: opts.NewBranch}
		}

		// Otherwise, delete branch from local copy in case out of sync
		if git.RepoHasBranch(localPath, opts.NewBranch) {
			if err := git.DeleteBranch(localPath, opts.NewBranch, git.DeleteBranchOptions{
				Force: true,
			}); err != nil {
				return fmt.Errorf("delete branch %q: %v", opts.NewBranch, err)
			}
		}

		if err := r.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil {
			return fmt.Errorf("checkout new branch[%s] from old branch[%s]: %v", opts.NewBranch, opts.OldBranch, err)
		}
	}