| @@ -7,8 +7,6 @@ package models | |||||
| import ( | import ( | ||||
| "fmt" | "fmt" | ||||
| "os" | |||||
| "path" | |||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/modules/git" | "code.gitea.io/gitea/modules/git" | ||||
| @@ -631,48 +629,6 @@ func (pr *PullRequest) UpdateCols(cols ...string) error { | |||||
| return err | return err | ||||
| } | } | ||||
| // PushToBaseRepo pushes commits from branches of head repository to | |||||
| // corresponding branches of base repository. | |||||
| // FIXME: Only push branches that are actually updates? | |||||
| func (pr *PullRequest) PushToBaseRepo() (err error) { | |||||
| log.Trace("PushToBaseRepo[%d]: pushing commits to base repo '%s'", pr.BaseRepoID, pr.GetGitRefName()) | |||||
| headRepoPath := pr.HeadRepo.RepoPath() | |||||
| headGitRepo, err := git.OpenRepository(headRepoPath) | |||||
| if err != nil { | |||||
| return fmt.Errorf("OpenRepository: %v", err) | |||||
| } | |||||
| defer headGitRepo.Close() | |||||
| tmpRemoteName := fmt.Sprintf("tmp-pull-%d", pr.ID) | |||||
| if err = headGitRepo.AddRemote(tmpRemoteName, pr.BaseRepo.RepoPath(), false); err != nil { | |||||
| return fmt.Errorf("headGitRepo.AddRemote: %v", err) | |||||
| } | |||||
| // Make sure to remove the remote even if the push fails | |||||
| defer func() { | |||||
| if err := headGitRepo.RemoveRemote(tmpRemoteName); err != nil { | |||||
| log.Error("PushToBaseRepo: RemoveRemote: %s", err) | |||||
| } | |||||
| }() | |||||
| headFile := pr.GetGitRefName() | |||||
| // Remove head in case there is a conflict. | |||||
| file := path.Join(pr.BaseRepo.RepoPath(), headFile) | |||||
| _ = os.Remove(file) | |||||
| if err = git.Push(headRepoPath, git.PushOptions{ | |||||
| Remote: tmpRemoteName, | |||||
| Branch: fmt.Sprintf("%s:%s", pr.HeadBranch, headFile), | |||||
| Force: true, | |||||
| }); err != nil { | |||||
| return fmt.Errorf("Push: %v", err) | |||||
| } | |||||
| return nil | |||||
| } | |||||
| // IsWorkInProgress determine if the Pull Request is a Work In Progress by its title | // IsWorkInProgress determine if the Pull Request is a Work In Progress by its title | ||||
| func (pr *PullRequest) IsWorkInProgress() bool { | func (pr *PullRequest) IsWorkInProgress() bool { | ||||
| if err := pr.LoadIssue(); err != nil { | if err := pr.LoadIssue(); err != nil { | ||||
| @@ -190,8 +190,6 @@ func TestPullRequest_UpdateCols(t *testing.T) { | |||||
| CheckConsistencyFor(t, pr) | CheckConsistencyFor(t, pr) | ||||
| } | } | ||||
| // TODO TestPullRequest_PushToBaseRepo | |||||
| func TestPullRequestList_LoadAttributes(t *testing.T) { | func TestPullRequestList_LoadAttributes(t *testing.T) { | ||||
| assert.NoError(t, PrepareTestDatabase()) | assert.NoError(t, PrepareTestDatabase()) | ||||
| @@ -307,9 +307,6 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption | |||||
| } | } | ||||
| ctx.Error(500, "NewPullRequest", err) | ctx.Error(500, "NewPullRequest", err) | ||||
| return | return | ||||
| } else if err := pr.PushToBaseRepo(); err != nil { | |||||
| ctx.Error(500, "PushToBaseRepo", err) | |||||
| return | |||||
| } | } | ||||
| notification.NotifyNewPullRequest(pr) | notification.NotifyNewPullRequest(pr) | ||||
| @@ -813,9 +813,6 @@ func CompareAndPullRequestPost(ctx *context.Context, form auth.CreateIssueForm) | |||||
| } | } | ||||
| ctx.ServerError("NewPullRequest", err) | ctx.ServerError("NewPullRequest", err) | ||||
| return | return | ||||
| } else if err := pullRequest.PushToBaseRepo(); err != nil { | |||||
| ctx.ServerError("PushToBaseRepo", err) | |||||
| return | |||||
| } | } | ||||
| notification.NotifyNewPullRequest(pullRequest) | notification.NotifyNewPullRequest(pullRequest) | ||||
| @@ -6,6 +6,8 @@ package pull | |||||
| import ( | import ( | ||||
| "fmt" | "fmt" | ||||
| "os" | |||||
| "path" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/git" | "code.gitea.io/gitea/modules/git" | ||||
| @@ -33,6 +35,10 @@ func NewPullRequest(repo *models.Repository, pull *models.Issue, labelIDs []int6 | |||||
| pr.Issue = pull | pr.Issue = pull | ||||
| pull.PullRequest = pr | pull.PullRequest = pr | ||||
| if err := PushToBaseRepo(pr); err != nil { | |||||
| return err | |||||
| } | |||||
| notification.NotifyNewPullRequest(pr) | notification.NotifyNewPullRequest(pr) | ||||
| return nil | return nil | ||||
| @@ -60,7 +66,7 @@ func checkForInvalidation(requests models.PullRequestList, repoID int64, doer *m | |||||
| func addHeadRepoTasks(prs []*models.PullRequest) { | func addHeadRepoTasks(prs []*models.PullRequest) { | ||||
| for _, pr := range prs { | for _, pr := range prs { | ||||
| log.Trace("addHeadRepoTasks[%d]: composing new test task", pr.ID) | log.Trace("addHeadRepoTasks[%d]: composing new test task", pr.ID) | ||||
| if err := pr.PushToBaseRepo(); err != nil { | |||||
| if err := PushToBaseRepo(pr); err != nil { | |||||
| log.Error("PushToBaseRepo: %v", err) | log.Error("PushToBaseRepo: %v", err) | ||||
| continue | continue | ||||
| } | } | ||||
| @@ -107,3 +113,45 @@ func AddTestPullRequestTask(doer *models.User, repoID int64, branch string, isSy | |||||
| AddToTaskQueue(pr) | AddToTaskQueue(pr) | ||||
| } | } | ||||
| } | } | ||||
| // PushToBaseRepo pushes commits from branches of head repository to | |||||
| // corresponding branches of base repository. | |||||
| // FIXME: Only push branches that are actually updates? | |||||
| func PushToBaseRepo(pr *models.PullRequest) (err error) { | |||||
| log.Trace("PushToBaseRepo[%d]: pushing commits to base repo '%s'", pr.BaseRepoID, pr.GetGitRefName()) | |||||
| headRepoPath := pr.HeadRepo.RepoPath() | |||||
| headGitRepo, err := git.OpenRepository(headRepoPath) | |||||
| if err != nil { | |||||
| return fmt.Errorf("OpenRepository: %v", err) | |||||
| } | |||||
| defer headGitRepo.Close() | |||||
| tmpRemoteName := fmt.Sprintf("tmp-pull-%d", pr.ID) | |||||
| if err = headGitRepo.AddRemote(tmpRemoteName, pr.BaseRepo.RepoPath(), false); err != nil { | |||||
| return fmt.Errorf("headGitRepo.AddRemote: %v", err) | |||||
| } | |||||
| // Make sure to remove the remote even if the push fails | |||||
| defer func() { | |||||
| if err := headGitRepo.RemoveRemote(tmpRemoteName); err != nil { | |||||
| log.Error("PushToBaseRepo: RemoveRemote: %s", err) | |||||
| } | |||||
| }() | |||||
| headFile := pr.GetGitRefName() | |||||
| // Remove head in case there is a conflict. | |||||
| file := path.Join(pr.BaseRepo.RepoPath(), headFile) | |||||
| _ = os.Remove(file) | |||||
| if err = git.Push(headRepoPath, git.PushOptions{ | |||||
| Remote: tmpRemoteName, | |||||
| Branch: fmt.Sprintf("%s:%s", pr.HeadBranch, headFile), | |||||
| Force: true, | |||||
| }); err != nil { | |||||
| return fmt.Errorf("Push: %v", err) | |||||
| } | |||||
| return nil | |||||
| } | |||||
| @@ -0,0 +1,8 @@ | |||||
| // Copyright 2019 The Gitea Authors. | |||||
| // All rights reserved. | |||||
| // Use of this source code is governed by a MIT-style | |||||
| // license that can be found in the LICENSE file. | |||||
| package pull | |||||
| // TODO TestPullRequest_PushToBaseRepo | |||||