func (repo *Repository) DeleteWikiPage(doer *User, title string) (err error) { wikiWorkingPool.CheckIn(com.ToStr(repo.ID)) defer wikiWorkingPool.CheckOut(com.ToStr(repo.ID)) localPath := repo.LocalWikiPath() if err = discardLocalWikiChanges(localPath); err != nil { return fmt.Errorf("discardLocalWikiChanges: %v", err) } else if err = repo.UpdateLocalWiki(); err != nil { return fmt.Errorf("UpdateLocalWiki: %v", err) } title = ToWikiPageName(title) filename := path.Join(localPath, title+".md") os.Remove(filename) message := "Delete page '" + title + "'" if err = git.AddChanges(localPath, true); err != nil { return fmt.Errorf("AddChanges: %v", err) } else if err = git.CommitChanges(localPath, git.CommitChangesOptions{ Committer: doer.NewGitSig(), Message: message, }); err != nil { return fmt.Errorf("CommitChanges: %v", err) } else if err = git.Push(localPath, "origin", "master"); err != nil { return fmt.Errorf("Push: %v", err) } return nil }
// updateWikiPage adds new page to repository wiki. func (repo *Repository) updateWikiPage(doer *User, oldTitle, title, content, message string, isNew bool) (err error) { wikiWorkingPool.CheckIn(com.ToStr(repo.ID)) defer wikiWorkingPool.CheckOut(com.ToStr(repo.ID)) if err = repo.InitWiki(); err != nil { return fmt.Errorf("InitWiki: %v", err) } localPath := repo.LocalWikiPath() if err = discardLocalWikiChanges(localPath); err != nil { return fmt.Errorf("discardLocalWikiChanges: %v", err) } else if err = repo.UpdateLocalWiki(); err != nil { return fmt.Errorf("UpdateLocalWiki: %v", err) } title = ToWikiPageName(title) filename := path.Join(localPath, title+".md") // If not a new file, show perform update not create. if isNew { if com.IsExist(filename) { return ErrWikiAlreadyExist{filename} } } else { os.Remove(path.Join(localPath, oldTitle+".md")) } // SECURITY: if new file is a symlink to non-exist critical file, // attack content can be written to the target file (e.g. authorized_keys2) // as a new page operation. // So we want to make sure the symlink is removed before write anything. // The new file we created will be in normal text format. os.Remove(filename) if err = ioutil.WriteFile(filename, []byte(content), 0666); err != nil { return fmt.Errorf("WriteFile: %v", err) } if len(message) == 0 { message = "Update page '" + title + "'" } if err = git.AddChanges(localPath, true); err != nil { return fmt.Errorf("AddChanges: %v", err) } else if err = git.CommitChanges(localPath, git.CommitChangesOptions{ Committer: doer.NewGitSig(), Message: message, }); err != nil { return fmt.Errorf("CommitChanges: %v", err) } else if err = git.Push(localPath, "origin", "master"); err != nil { return fmt.Errorf("Push: %v", err) } return nil }
func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) (err error) { if len(opts.Files) == 0 { return nil } uploads, err := GetUploadsByUUIDs(opts.Files) if err != nil { return fmt.Errorf("GetUploadsByUUIDs [uuids: %v]: %v", opts.Files, err) } repoWorkingPool.CheckIn(com.ToStr(repo.ID)) defer repoWorkingPool.CheckOut(com.ToStr(repo.ID)) if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil { return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err) } else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil { return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err) } if opts.OldBranch != opts.NewBranch { if err = repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil { return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err) } } localPath := repo.LocalCopyPath() dirPath := path.Join(localPath, opts.TreePath) os.MkdirAll(dirPath, os.ModePerm) // Copy uploaded files into repository. for _, upload := range uploads { tmpPath := upload.LocalPath() targetPath := path.Join(dirPath, upload.Name) if !com.IsFile(tmpPath) { continue } if err = com.Copy(tmpPath, targetPath); err != nil { return fmt.Errorf("Copy: %v", err) } } if err = git.AddChanges(localPath, true); err != nil { return fmt.Errorf("git add --all: %v", err) } else if err = git.CommitChanges(localPath, git.CommitChangesOptions{ Committer: doer.NewGitSig(), Message: opts.Message, }); err != nil { return fmt.Errorf("CommitChanges: %v", err) } else if err = git.Push(localPath, "origin", opts.NewBranch); err != nil { return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err) } gitRepo, err := git.OpenRepository(repo.RepoPath()) if err != nil { log.Error(4, "OpenRepository: %v", err) return nil } commit, err := gitRepo.GetBranchCommit(opts.NewBranch) if err != nil { log.Error(4, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err) return nil } // Simulate push event. pushCommits := &PushCommits{ Len: 1, Commits: []*PushCommit{CommitToPushCommit(commit)}, } if err := CommitRepoAction(CommitRepoActionOptions{ PusherName: doer.Name, RepoOwnerID: repo.MustOwner().ID, RepoName: repo.Name, RefFullName: git.BRANCH_PREFIX + opts.NewBranch, OldCommitID: opts.LastCommitID, NewCommitID: commit.ID.String(), Commits: pushCommits, }); err != nil { log.Error(4, "CommitRepoAction: %v", err) return nil } return DeleteUploads(uploads...) }
// UpdateRepoFile adds or updates a file in repository. func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (err error) { repoWorkingPool.CheckIn(com.ToStr(repo.ID)) defer repoWorkingPool.CheckOut(com.ToStr(repo.ID)) if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil { return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err) } else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil { return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err) } if opts.OldBranch != opts.NewBranch { if err := repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil { return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err) } } localPath := repo.LocalCopyPath() oldFilePath := path.Join(localPath, opts.OldTreeName) filePath := path.Join(localPath, opts.NewTreeName) os.MkdirAll(path.Dir(filePath), os.ModePerm) // If it's meant to be a new file, make sure it doesn't exist. if opts.IsNewFile { if com.IsExist(filePath) { return ErrRepoFileAlreadyExist{filePath} } } // Ignore move step if it's a new file under a directory. // Otherwise, move the file when name changed. if com.IsFile(oldFilePath) && opts.OldTreeName != opts.NewTreeName { if err = git.MoveFile(localPath, opts.OldTreeName, opts.NewTreeName); err != nil { return fmt.Errorf("git mv %s %s: %v", opts.OldTreeName, opts.NewTreeName, err) } } if err = ioutil.WriteFile(filePath, []byte(opts.Content), 0666); err != nil { return fmt.Errorf("WriteFile: %v", err) } if err = git.AddChanges(localPath, true); err != nil { return fmt.Errorf("git add --all: %v", err) } else if err = git.CommitChanges(localPath, git.CommitChangesOptions{ Committer: doer.NewGitSig(), Message: opts.Message, }); err != nil { return fmt.Errorf("CommitChanges: %v", err) } else if err = git.Push(localPath, "origin", opts.NewBranch); err != nil { return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err) } gitRepo, err := git.OpenRepository(repo.RepoPath()) if err != nil { log.Error(4, "OpenRepository: %v", err) return nil } commit, err := gitRepo.GetBranchCommit(opts.NewBranch) if err != nil { log.Error(4, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err) return nil } // Simulate push event. pushCommits := &PushCommits{ Len: 1, Commits: []*PushCommit{CommitToPushCommit(commit)}, } oldCommitID := opts.LastCommitID if opts.NewBranch != opts.OldBranch { oldCommitID = git.EMPTY_SHA } if err := CommitRepoAction(CommitRepoActionOptions{ PusherName: doer.Name, RepoOwnerID: repo.MustOwner().ID, RepoName: repo.Name, RefFullName: git.BRANCH_PREFIX + opts.NewBranch, OldCommitID: oldCommitID, NewCommitID: commit.ID.String(), Commits: pushCommits, }); err != nil { log.Error(4, "CommitRepoAction: %v", err) return nil } return nil }
func (repo *Repository) DeleteRepoFile(doer *User, opts DeleteRepoFileOptions) (err error) { repoWorkingPool.CheckIn(com.ToStr(repo.ID)) defer repoWorkingPool.CheckOut(com.ToStr(repo.ID)) if err = repo.DiscardLocalRepoBranchChanges(opts.OldBranch); err != nil { return fmt.Errorf("DiscardLocalRepoBranchChanges [branch: %s]: %v", opts.OldBranch, err) } else if err = repo.UpdateLocalCopyBranch(opts.OldBranch); err != nil { return fmt.Errorf("UpdateLocalCopyBranch [branch: %s]: %v", opts.OldBranch, err) } if opts.OldBranch != opts.NewBranch { if err := repo.CheckoutNewBranch(opts.OldBranch, opts.NewBranch); err != nil { return fmt.Errorf("CheckoutNewBranch [old_branch: %s, new_branch: %s]: %v", opts.OldBranch, opts.NewBranch, err) } } localPath := repo.LocalCopyPath() if err = os.Remove(path.Join(localPath, opts.TreePath)); err != nil { return fmt.Errorf("Remove: %v", err) } if err = git.AddChanges(localPath, true); err != nil { return fmt.Errorf("git add --all: %v", err) } else if err = git.CommitChanges(localPath, git.CommitChangesOptions{ Committer: doer.NewGitSig(), Message: opts.Message, }); err != nil { return fmt.Errorf("CommitChanges: %v", err) } else if err = git.Push(localPath, "origin", opts.NewBranch); err != nil { return fmt.Errorf("git push origin %s: %v", opts.NewBranch, err) } gitRepo, err := git.OpenRepository(repo.RepoPath()) if err != nil { log.Error(4, "OpenRepository: %v", err) return nil } commit, err := gitRepo.GetBranchCommit(opts.NewBranch) if err != nil { log.Error(4, "GetBranchCommit [branch: %s]: %v", opts.NewBranch, err) return nil } // Simulate push event. pushCommits := &PushCommits{ Len: 1, Commits: []*PushCommit{CommitToPushCommit(commit)}, } if err := CommitRepoAction(CommitRepoActionOptions{ PusherName: doer.Name, RepoOwnerID: repo.MustOwner().ID, RepoName: repo.Name, RefFullName: git.BRANCH_PREFIX + opts.NewBranch, OldCommitID: opts.LastCommitID, NewCommitID: commit.ID.String(), Commits: pushCommits, }); err != nil { log.Error(4, "CommitRepoAction: %v", err) return nil } return nil }