From f2d12f7b034e32d0e7cc7b60e7ad015af122db3f Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 25 Jan 2020 10:48:22 +0800 Subject: Fix pull view when head repository or head branch missed and close related pull requests when delete head repository or head branch (#9927) * fix pull view when head repository or head branch missed and close related pull requests when delete branch * fix pull view broken when head repository deleted * close pull requests when head repositories deleted * Add tests for broken pull request head repository or branch * fix typo * ignore special error when close pull request Co-authored-by: Lauris BH --- services/pull/pull.go | 76 +++++++++++++++++++++++++++++++++++++++ services/repository/repository.go | 5 +++ 2 files changed, 81 insertions(+) (limited to 'services') diff --git a/services/pull/pull.go b/services/pull/pull.go index bc71e52213..705eab06a2 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -355,3 +355,79 @@ func PushToBaseRepo(pr *models.PullRequest) (err error) { return nil } + +type errlist []error + +func (errs errlist) Error() string { + if len(errs) > 0 { + var buf strings.Builder + for i, err := range errs { + if i > 0 { + buf.WriteString(", ") + } + buf.WriteString(err.Error()) + } + return buf.String() + } + return "" +} + +// CloseBranchPulls close all the pull requests who's head branch is the branch +func CloseBranchPulls(doer *models.User, repoID int64, branch string) error { + prs, err := models.GetUnmergedPullRequestsByHeadInfo(repoID, branch) + if err != nil { + return err + } + + prs2, err := models.GetUnmergedPullRequestsByBaseInfo(repoID, branch) + if err != nil { + return err + } + + prs = append(prs, prs2...) + if err := models.PullRequestList(prs).LoadAttributes(); err != nil { + return err + } + + var errs errlist + for _, pr := range prs { + if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !models.IsErrIssueWasClosed(err) { + errs = append(errs, err) + } + } + if len(errs) > 0 { + return errs + } + return nil +} + +// CloseRepoBranchesPulls close all pull requests which head branches are in the given repository +func CloseRepoBranchesPulls(doer *models.User, repo *models.Repository) error { + branches, err := git.GetBranchesByPath(repo.RepoPath()) + if err != nil { + return err + } + + var errs errlist + for _, branch := range branches { + prs, err := models.GetUnmergedPullRequestsByHeadInfo(repo.ID, branch.Name) + if err != nil { + return err + } + + if err = models.PullRequestList(prs).LoadAttributes(); err != nil { + return err + } + + for _, pr := range prs { + if err = issue_service.ChangeStatus(pr.Issue, doer, true); err != nil && !models.IsErrIssueWasClosed(err) { + errs = append(errs, err) + } + } + } + + if len(errs) > 0 { + return errs + } + return nil +} diff --git a/services/repository/repository.go b/services/repository/repository.go index eea8b352b4..f50b98b640 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" repo_module "code.gitea.io/gitea/modules/repository" + pull_service "code.gitea.io/gitea/services/pull" ) // CreateRepository creates a repository for the user/organization. @@ -49,6 +50,10 @@ func ForkRepository(doer, u *models.User, oldRepo *models.Repository, name, desc // DeleteRepository deletes a repository for a user or organization. func DeleteRepository(doer *models.User, repo *models.Repository) error { + if err := pull_service.CloseRepoBranchesPulls(doer, repo); err != nil { + log.Error("CloseRepoBranchesPulls failed: %v", err) + } + if err := models.DeleteRepository(doer, repo.OwnerID, repo.ID); err != nil { return err } -- cgit v1.2.3