@@ -23,7 +23,6 @@ import (
23
23
"code.gitea.io/gitea/modules/json"
24
24
"code.gitea.io/gitea/modules/log"
25
25
"code.gitea.io/gitea/modules/notification"
26
- "code.gitea.io/gitea/modules/process"
27
26
repo_module "code.gitea.io/gitea/modules/repository"
28
27
"code.gitea.io/gitea/modules/setting"
29
28
"code.gitea.io/gitea/modules/sync"
@@ -35,73 +34,70 @@ import (
35
34
var pullWorkingPool = sync .NewExclusivePool ()
36
35
37
36
// 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 )
44
39
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 )
57
42
}
43
+ return err
58
44
}
45
+ defer cancel ()
59
46
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 {
75
48
return err
76
49
}
77
50
78
- mentions , err := issues_model . FindAndUpdateIssueMentions (ctx , pull , pull . Poster , pull . Content )
51
+ divergence , err := git . GetDivergingCommits (ctx , prCtx . tmpBasePath , baseBranch , trackingBranch )
79
52
if err != nil {
80
53
return err
81
54
}
55
+ pr .CommitsAhead = divergence .Ahead
56
+ pr .CommitsBehind = divergence .Behind
82
57
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 )
90
59
91
60
// add first push codes comment
92
- baseGitRepo , err := git .OpenRepository (prCtx , pr .BaseRepo .RepoPath ())
61
+ baseGitRepo , err := git .OpenRepository (ctx , pr .BaseRepo .RepoPath ())
93
62
if err != nil {
94
63
return err
95
64
}
96
65
defer baseGitRepo .Close ()
97
66
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
+ }
103
100
104
- if len (compareInfo .Commits ) > 0 {
105
101
data := issues_model.PushActionContent {IsForcePush : false }
106
102
data .CommitIDs = make ([]string , 0 , len (compareInfo .Commits ))
107
103
for i := len (compareInfo .Commits ) - 1 ; i >= 0 ; i -- {
@@ -115,14 +111,47 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, pull *issu
115
111
116
112
ops := & issues_model.CreateCommentOptions {
117
113
Type : issues_model .CommentTypePullRequestPush ,
118
- Doer : pull .Poster ,
114
+ Doer : issue .Poster ,
119
115
Repo : repo ,
120
116
Issue : pr .Issue ,
121
117
IsForcePush : false ,
122
118
Content : string (dataJSON ),
123
119
}
124
120
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
+ }
126
155
}
127
156
128
157
return nil
0 commit comments