@@ -31,6 +31,163 @@ import (
3131 pull_service "code.gitea.io/gitea/services/pull"
3232)
3333
34+ func newCommentWithReopen (ctx * context.Context , issue * issues_model.Issue , content string , attachments []string ) * issues_model.Comment {
35+ if ! issue .IsClosed {
36+ ctx .JSONError (ctx .Tr ("repo.issues.not_closed" ))
37+ return nil
38+ }
39+
40+ if ! ctx .Repo .CanWriteIssuesOrPulls (issue .IsPull ) &&
41+ ! issue .IsPoster (ctx .Doer .ID ) &&
42+ ! ctx .Doer .IsAdmin {
43+ ctx .JSONError (ctx .Tr ("repo.issues.reopen_not_allowed" ))
44+ return nil
45+ }
46+
47+ if issue .IsPull {
48+ pull := issue .PullRequest
49+ if pull .HasMerged {
50+ ctx .JSONError (ctx .Tr ("repo.issues.reopen_not_allowed_merged" ))
51+ return nil
52+ }
53+
54+ // get head commit of branch in the head repo
55+ if err := pull .LoadHeadRepo (ctx ); err != nil {
56+ ctx .ServerError ("Unable to load head repo" , err )
57+ return nil
58+ }
59+
60+ // check whether the ref of PR <refs/pulls/pr_index/head> in base repo is consistent with the head commit of head branch in the head repo
61+ // get head commit of PR
62+ if pull .Flow == issues_model .PullRequestFlowGithub {
63+ prHeadRef := pull .GetGitHeadRefName ()
64+ if err := pull .LoadBaseRepo (ctx ); err != nil {
65+ ctx .ServerError ("Unable to load base repo" , err )
66+ return nil
67+ }
68+ prHeadCommitID , err := git .GetFullCommitID (ctx , pull .BaseRepo .RepoPath (), prHeadRef )
69+ if err != nil {
70+ ctx .ServerError ("Get head commit Id of pr fail" , err )
71+ return nil
72+ }
73+
74+ if ok := gitrepo .IsBranchExist (ctx , pull .HeadRepo , pull .BaseBranch ); ! ok {
75+ // todo localize
76+ ctx .JSONError ("The origin branch is delete, cannot reopen." )
77+ return nil
78+ }
79+ headBranchRef := git .RefNameFromBranch (pull .HeadBranch )
80+ headBranchCommitID , err := git .GetFullCommitID (ctx , pull .HeadRepo .RepoPath (), headBranchRef .String ())
81+ if err != nil {
82+ ctx .ServerError ("Get head commit Id of head branch fail" , err )
83+ return nil
84+ }
85+
86+ err = pull .LoadIssue (ctx )
87+ if err != nil {
88+ ctx .ServerError ("load the issue of pull request error" , err )
89+ return nil
90+ }
91+
92+ if prHeadCommitID != headBranchCommitID {
93+ // force push to base repo
94+ err := git .Push (ctx , pull .HeadRepo .RepoPath (), git.PushOptions {
95+ Remote : pull .BaseRepo .RepoPath (),
96+ Branch : pull .HeadBranch + ":" + prHeadRef ,
97+ Force : true ,
98+ Env : repo_module .InternalPushingEnvironment (pull .Issue .Poster , pull .BaseRepo ),
99+ })
100+ if err != nil {
101+ ctx .ServerError ("force push error" , err )
102+ return nil
103+ }
104+ }
105+ }
106+
107+ branchExist , err := git_model .IsBranchExist (ctx , pull .HeadRepo .ID , pull .HeadBranch )
108+ if err != nil {
109+ ctx .ServerError ("IsBranchExist" , err )
110+ return nil
111+ }
112+ if ! branchExist {
113+ ctx .JSONError (ctx .Tr ("repo.pulls.head_branch_not_exist" ))
114+ return nil
115+ }
116+
117+ // check if an opened pull request exists with the same head branch and base branch
118+ pr , err := issues_model .GetUnmergedPullRequest (ctx , pull .HeadRepoID , pull .BaseRepoID , pull .HeadBranch , pull .BaseBranch , pull .Flow )
119+ if err != nil {
120+ if ! issues_model .IsErrPullRequestNotExist (err ) {
121+ ctx .JSONError (err .Error ())
122+ return nil
123+ }
124+ }
125+ if pr != nil {
126+ ctx .Flash .Info (ctx .Tr ("repo.pulls.open_unmerged_pull_exists" , pr .Index ))
127+ return nil
128+ }
129+ }
130+
131+ createdComment , err := issue_service .ReopenIssueWithComment (ctx , issue , ctx .Doer , "" , content , attachments )
132+ if err != nil {
133+ if errors .Is (err , user_model .ErrBlockedUser ) {
134+ ctx .JSONError (ctx .Tr ("repo.issues.comment.blocked_user" ))
135+ } else {
136+ ctx .ServerError ("ReopenIssue" , err )
137+ }
138+ return nil
139+ }
140+
141+ if issue .IsPull {
142+ pull := issue .PullRequest
143+ // check whether the ref of PR <refs/pulls/pr_index/head> in base repo is consistent with the head commit of head branch in the head repo
144+ // get head commit of PR
145+ if pull .Flow == issues_model .PullRequestFlowGithub {
146+ prHeadRef := pull .GetGitHeadRefName ()
147+ if err := pull .LoadBaseRepo (ctx ); err != nil {
148+ ctx .ServerError ("Unable to load base repo" , err )
149+ return nil
150+ }
151+ prHeadCommitID , err := ctx .Repo .GitRepo .GetRefCommitID (prHeadRef )
152+ if err != nil {
153+ ctx .ServerError ("Get head commit Id of pr fail" , err )
154+ return nil
155+ }
156+
157+ headBranchCommitID , err := gitrepo .GetBranchCommitID (ctx , pull .HeadRepo , pull .HeadBranch )
158+ if err != nil {
159+ ctx .ServerError ("Get head commit Id of head branch fail" , err )
160+ return nil
161+ }
162+
163+ if err = pull .LoadIssue (ctx ); err != nil {
164+ ctx .ServerError ("load the issue of pull request error" , err )
165+ return nil
166+ }
167+
168+ // if the head commit ID of the PR is different from the head branch
169+ if prHeadCommitID != headBranchCommitID {
170+ // force push to base repo
171+ err := git .Push (ctx , pull .HeadRepo .RepoPath (), git.PushOptions {
172+ Remote : pull .BaseRepo .RepoPath (),
173+ Branch : pull .HeadBranch + ":" + prHeadRef ,
174+ Force : true ,
175+ Env : repo_module .InternalPushingEnvironment (pull .Issue .Poster , pull .BaseRepo ),
176+ })
177+ if err != nil {
178+ ctx .ServerError ("force push error" , err )
179+ return nil
180+ }
181+ }
182+ }
183+
184+ // Regenerate patch and test conflict.
185+ pull .HeadCommitID = ""
186+ pull_service .StartPullRequestCheckImmediately (ctx , pull )
187+ }
188+ return createdComment
189+ }
190+
34191// NewComment create a comment for issue
35192func NewComment (ctx * context.Context ) {
36193 form := web .GetForm (ctx ).(* forms.CreateCommentForm )
@@ -82,160 +239,10 @@ func NewComment(ctx *context.Context) {
82239
83240 switch form .Status {
84241 case "reopen" :
85- if ! issue . IsClosed {
86- ctx .JSONError ( ctx . Tr ( "repo.issues.not_closed" ))
242+ createdComment = newCommentWithReopen ( ctx , issue , form . Content , attachments )
243+ if ctx .Written () {
87244 return
88245 }
89-
90- if ! ctx .Repo .CanWriteIssuesOrPulls (issue .IsPull ) &&
91- ! issue .IsPoster (ctx .Doer .ID ) &&
92- ! ctx .Doer .IsAdmin {
93- ctx .JSONError (ctx .Tr ("repo.issues.reopen_not_allowed" ))
94- return
95- }
96-
97- if issue .IsPull {
98- pull := issue .PullRequest
99- if pull .HasMerged {
100- ctx .JSONError (ctx .Tr ("repo.issues.reopen_not_allowed_merged" ))
101- return
102- }
103-
104- // get head commit of branch in the head repo
105- if err := pull .LoadHeadRepo (ctx ); err != nil {
106- ctx .ServerError ("Unable to load head repo" , err )
107- return
108- }
109-
110- // check whether the ref of PR <refs/pulls/pr_index/head> in base repo is consistent with the head commit of head branch in the head repo
111- // get head commit of PR
112- if pull .Flow == issues_model .PullRequestFlowGithub {
113- prHeadRef := pull .GetGitHeadRefName ()
114- if err := pull .LoadBaseRepo (ctx ); err != nil {
115- ctx .ServerError ("Unable to load base repo" , err )
116- return
117- }
118- prHeadCommitID , err := git .GetFullCommitID (ctx , pull .BaseRepo .RepoPath (), prHeadRef )
119- if err != nil {
120- ctx .ServerError ("Get head commit Id of pr fail" , err )
121- return
122- }
123-
124- if ok := gitrepo .IsBranchExist (ctx , pull .HeadRepo , pull .BaseBranch ); ! ok {
125- // todo localize
126- ctx .JSONError ("The origin branch is delete, cannot reopen." )
127- return
128- }
129- headBranchRef := git .RefNameFromBranch (pull .HeadBranch )
130- headBranchCommitID , err := git .GetFullCommitID (ctx , pull .HeadRepo .RepoPath (), headBranchRef .String ())
131- if err != nil {
132- ctx .ServerError ("Get head commit Id of head branch fail" , err )
133- return
134- }
135-
136- err = pull .LoadIssue (ctx )
137- if err != nil {
138- ctx .ServerError ("load the issue of pull request error" , err )
139- return
140- }
141-
142- if prHeadCommitID != headBranchCommitID {
143- // force push to base repo
144- err := git .Push (ctx , pull .HeadRepo .RepoPath (), git.PushOptions {
145- Remote : pull .BaseRepo .RepoPath (),
146- Branch : pull .HeadBranch + ":" + prHeadRef ,
147- Force : true ,
148- Env : repo_module .InternalPushingEnvironment (pull .Issue .Poster , pull .BaseRepo ),
149- })
150- if err != nil {
151- ctx .ServerError ("force push error" , err )
152- return
153- }
154- }
155- }
156-
157- branchExist , err := git_model .IsBranchExist (ctx , pull .HeadRepo .ID , pull .HeadBranch )
158- if err != nil {
159- ctx .ServerError ("IsBranchExist" , err )
160- return
161- }
162- if ! branchExist {
163- ctx .JSONError (ctx .Tr ("repo.pulls.head_branch_not_exist" ))
164- return
165- }
166-
167- // check if an opened pull request exists with the same head branch and base branch
168- pr , err := issues_model .GetUnmergedPullRequest (ctx , pull .HeadRepoID , pull .BaseRepoID , pull .HeadBranch , pull .BaseBranch , pull .Flow )
169- if err != nil {
170- if ! issues_model .IsErrPullRequestNotExist (err ) {
171- ctx .JSONError (err .Error ())
172- return
173- }
174- }
175- if pr != nil {
176- ctx .Flash .Info (ctx .Tr ("repo.pulls.open_unmerged_pull_exists" , pr .Index ))
177- return
178- }
179- }
180-
181- createdComment , err = issue_service .ReopenIssueWithComment (ctx , issue , ctx .Doer , "" , form .Content , attachments )
182- if err != nil {
183- if errors .Is (err , user_model .ErrBlockedUser ) {
184- ctx .JSONError (ctx .Tr ("repo.issues.comment.blocked_user" ))
185- } else {
186- ctx .ServerError ("ReopenIssue" , err )
187- }
188- return
189- }
190-
191- if issue .IsPull {
192- pull := issue .PullRequest
193- // check whether the ref of PR <refs/pulls/pr_index/head> in base repo is consistent with the head commit of head branch in the head repo
194- // get head commit of PR
195- if pull .Flow == issues_model .PullRequestFlowGithub {
196- prHeadRef := pull .GetGitHeadRefName ()
197- if err := pull .LoadBaseRepo (ctx ); err != nil {
198- ctx .ServerError ("Unable to load base repo" , err )
199- return
200- }
201- prHeadCommitID , err := git .GetFullCommitID (ctx , pull .BaseRepo .RepoPath (), prHeadRef )
202- if err != nil {
203- ctx .ServerError ("Get head commit Id of pr fail" , err )
204- return
205- }
206-
207- headBranchRef := pull .GetGitHeadBranchRefName ()
208- headBranchCommitID , err := git .GetFullCommitID (ctx , pull .HeadRepo .RepoPath (), headBranchRef )
209- if err != nil {
210- ctx .ServerError ("Get head commit Id of head branch fail" , err )
211- return
212- }
213-
214- if err = pull .LoadIssue (ctx ); err != nil {
215- ctx .ServerError ("load the issue of pull request error" , err )
216- return
217- }
218-
219- // if the head commit ID of the PR is different from the head branch
220- if prHeadCommitID != headBranchCommitID {
221- // force push to base repo
222- err := git .Push (ctx , pull .HeadRepo .RepoPath (), git.PushOptions {
223- Remote : pull .BaseRepo .RepoPath (),
224- Branch : pull .HeadBranch + ":" + prHeadRef ,
225- Force : true ,
226- Env : repo_module .InternalPushingEnvironment (pull .Issue .Poster , pull .BaseRepo ),
227- })
228- if err != nil {
229- ctx .ServerError ("force push error" , err )
230- return
231- }
232- }
233- }
234-
235- // Regenerate patch and test conflict.
236- pull .HeadCommitID = ""
237- pull_service .StartPullRequestCheckImmediately (ctx , pull )
238- }
239246 case "close" :
240247 if issue .IsClosed {
241248 ctx .JSONError (ctx .Tr ("repo.issues.already_closed" ))
0 commit comments