@@ -23,7 +23,6 @@ import (
2323 "code.gitea.io/gitea/modules/json"
2424 "code.gitea.io/gitea/modules/log"
2525 "code.gitea.io/gitea/modules/notification"
26- "code.gitea.io/gitea/modules/process"
2726 repo_module "code.gitea.io/gitea/modules/repository"
2827 "code.gitea.io/gitea/modules/setting"
2928 "code.gitea.io/gitea/modules/sync"
@@ -35,73 +34,70 @@ import (
3534var pullWorkingPool = sync .NewExclusivePool ()
3635
3736// NewPullRequest creates new pull request with labels for repository.
38- func NewPullRequest (ctx context.Context , repo * repo_model.Repository , pull * issues_model.Issue , labelIDs []int64 , uuids []string , pr * issues_model.PullRequest , assigneeIDs []int64 ) error {
39- if err := TestPatch (pr ); err != nil {
40- return err
41- }
42-
43- divergence , err := GetDiverging (ctx , pr )
37+ func NewPullRequest (ctx context.Context , repo * repo_model.Repository , issue * issues_model.Issue , labelIDs []int64 , uuids []string , pr * issues_model.PullRequest , assigneeIDs []int64 ) error {
38+ prCtx , cancel , err := createTemporaryRepoForPR (ctx , pr )
4439 if err != nil {
45- return err
46- }
47- pr .CommitsAhead = divergence .Ahead
48- pr .CommitsBehind = divergence .Behind
49-
50- if err := issues_model .NewPullRequest (ctx , repo , pull , labelIDs , uuids , pr ); err != nil {
51- return err
52- }
53-
54- for _ , assigneeID := range assigneeIDs {
55- if err := issue_service .AddAssigneeIfNotAssigned (ctx , pull , pull .Poster , assigneeID ); err != nil {
56- return err
40+ if ! models .IsErrBranchDoesNotExist (err ) {
41+ log .Error ("CreateTemporaryRepoForPR %-v: %v" , pr , err )
5742 }
43+ return err
5844 }
45+ defer cancel ()
5946
60- pr .Issue = pull
61- pull .PullRequest = pr
62-
63- // Now - even if the request context has been cancelled as the PR has been created
64- // in the db and there is no way to cancel that transaction we have to proceed - therefore
65- // create new context and work from there
66- prCtx , _ , finished := process .GetManager ().AddContext (graceful .GetManager ().HammerContext (), fmt .Sprintf ("NewPullRequest: %s:%d" , repo .FullName (), pr .Index ))
67- defer finished ()
68-
69- if pr .Flow == issues_model .PullRequestFlowGithub {
70- err = PushToBaseRepo (prCtx , pr )
71- } else {
72- err = UpdateRef (prCtx , pr )
73- }
74- if err != nil {
47+ if err := testPatch (ctx , prCtx , pr ); err != nil {
7548 return err
7649 }
7750
78- mentions , err := issues_model . FindAndUpdateIssueMentions (ctx , pull , pull . Poster , pull . Content )
51+ divergence , err := git . GetDivergingCommits (ctx , prCtx . tmpBasePath , baseBranch , trackingBranch )
7952 if err != nil {
8053 return err
8154 }
55+ pr .CommitsAhead = divergence .Ahead
56+ pr .CommitsBehind = divergence .Behind
8257
83- notification .NotifyNewPullRequest (prCtx , pr , mentions )
84- if len (pull .Labels ) > 0 {
85- notification .NotifyIssueChangeLabels (prCtx , pull .Poster , pull , pull .Labels , nil )
86- }
87- if pull .Milestone != nil {
88- notification .NotifyIssueChangeMilestone (prCtx , pull .Poster , pull , 0 )
89- }
58+ assigneeCommentMap := make (map [int64 ]* issues_model.Comment )
9059
9160 // add first push codes comment
92- baseGitRepo , err := git .OpenRepository (prCtx , pr .BaseRepo .RepoPath ())
61+ baseGitRepo , err := git .OpenRepository (ctx , pr .BaseRepo .RepoPath ())
9362 if err != nil {
9463 return err
9564 }
9665 defer baseGitRepo .Close ()
9766
98- compareInfo , err := baseGitRepo .GetCompareInfo (pr .BaseRepo .RepoPath (),
99- git .BranchPrefix + pr .BaseBranch , pr .GetGitRefName (), false , false )
100- if err != nil {
101- return err
102- }
67+ if err := db .WithTx (ctx , func (ctx context.Context ) error {
68+ if err := issues_model .NewPullRequest (ctx , repo , issue , labelIDs , uuids , pr ); err != nil {
69+ return err
70+ }
71+
72+ for _ , assigneeID := range assigneeIDs {
73+ comment , err := issue_service .AddAssigneeIfNotAssigned (ctx , issue , issue .Poster , assigneeID , false )
74+ if err != nil {
75+ return err
76+ }
77+ assigneeCommentMap [assigneeID ] = comment
78+ }
79+
80+ pr .Issue = issue
81+ issue .PullRequest = pr
82+
83+ if pr .Flow == issues_model .PullRequestFlowGithub {
84+ err = PushToBaseRepo (ctx , pr )
85+ } else {
86+ err = UpdateRef (ctx , pr )
87+ }
88+ if err != nil {
89+ return err
90+ }
91+
92+ compareInfo , err := baseGitRepo .GetCompareInfo (pr .BaseRepo .RepoPath (),
93+ git .BranchPrefix + pr .BaseBranch , pr .GetGitRefName (), false , false )
94+ if err != nil {
95+ return err
96+ }
97+ if len (compareInfo .Commits ) == 0 {
98+ return nil
99+ }
103100
104- if len (compareInfo .Commits ) > 0 {
105101 data := issues_model.PushActionContent {IsForcePush : false }
106102 data .CommitIDs = make ([]string , 0 , len (compareInfo .Commits ))
107103 for i := len (compareInfo .Commits ) - 1 ; i >= 0 ; i -- {
@@ -115,14 +111,47 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *issu
115111
116112 ops := & issues_model.CreateCommentOptions {
117113 Type : issues_model .CommentTypePullRequestPush ,
118- Doer : pull .Poster ,
114+ Doer : issue .Poster ,
119115 Repo : repo ,
120116 Issue : pr .Issue ,
121117 IsForcePush : false ,
122118 Content : string (dataJSON ),
123119 }
124120
125- _ , _ = issue_service .CreateComment (ctx , ops )
121+ if _ , err = issues_model .CreateComment (ctx , ops ); err != nil {
122+ return err
123+ }
124+
125+ return nil
126+ }); err != nil {
127+ // cleanup: this will only remove the reference, the real commit will be clean up when next GC
128+ if err1 := baseGitRepo .RemoveReference (pr .GetGitRefName ()); err1 != nil {
129+ log .Error ("RemoveReference: %v" , err1 )
130+ }
131+ return err
132+ }
133+ baseGitRepo .Close () // close immediately to avoid notifications will open the repository again
134+
135+ mentions , err := issues_model .FindAndUpdateIssueMentions (ctx , issue , issue .Poster , issue .Content )
136+ if err != nil {
137+ return err
138+ }
139+
140+ notification .NotifyNewPullRequest (ctx , pr , mentions )
141+ if len (issue .Labels ) > 0 {
142+ notification .NotifyIssueChangeLabels (ctx , issue .Poster , issue , issue .Labels , nil )
143+ }
144+ if issue .Milestone != nil {
145+ notification .NotifyIssueChangeMilestone (ctx , issue .Poster , issue , 0 )
146+ }
147+ if len (assigneeIDs ) > 0 {
148+ for _ , assigneeID := range assigneeIDs {
149+ assignee , err := user_model .GetUserByID (ctx , assigneeID )
150+ if err != nil {
151+ return ErrDependenciesLeft
152+ }
153+ notification .NotifyIssueChangeAssignee (ctx , issue .Poster , issue , assignee , false , assigneeCommentMap [assigneeID ])
154+ }
126155 }
127156
128157 return nil
0 commit comments