44package repo
55
66import (
7- "net/http"
8-
7+ git_model "code.gitea.io/gitea/models/git"
98 issues_model "code.gitea.io/gitea/models/issues"
9+ access_model "code.gitea.io/gitea/models/perm/access"
10+ repo_model "code.gitea.io/gitea/models/repo"
11+ unit_model "code.gitea.io/gitea/models/unit"
12+ "code.gitea.io/gitea/modules/git"
13+ "code.gitea.io/gitea/modules/gitrepo"
1014 "code.gitea.io/gitea/modules/web"
15+ "code.gitea.io/gitea/routers/utils"
1116 "code.gitea.io/gitea/services/context"
1217 "code.gitea.io/gitea/services/forms"
1318 repo_service "code.gitea.io/gitea/services/repository"
@@ -21,36 +26,84 @@ func CreateBranchFromIssue(ctx *context.Context) {
2126
2227 if issue .IsPull {
2328 ctx .Flash .Error (ctx .Tr ("repo.issues.create_branch_from_issue_error_is_pull" ))
24- ctx .Redirect (issue .Link (), http . StatusSeeOther )
29+ ctx .JSONRedirect (issue .Link ())
2530 return
2631 }
2732
2833 form := web .GetForm (ctx ).(* forms.NewBranchForm )
29- if ! ctx .Repo .CanCreateBranch () {
34+ repo := ctx .Repo .Repository
35+ gitRepo := ctx .Repo .GitRepo
36+ if form .RepoID > 0 {
37+ var err error
38+ repo , err = repo_model .GetRepositoryByID (ctx , form .RepoID )
39+ if err != nil {
40+ ctx .ServerError ("GetRepositoryByID" , err )
41+ return
42+ }
43+ gitRepo , err = gitrepo .OpenRepository (ctx , repo )
44+ if err != nil {
45+ ctx .ServerError ("GetRepositoryByID" , err )
46+ return
47+ }
48+ defer gitRepo .Close ()
49+ }
50+
51+ perm , err := access_model .GetUserRepoPermission (ctx , repo , ctx .Doer )
52+ if err != nil {
53+ ctx .ServerError ("GetRepositoryByID" , err )
54+ return
55+ }
56+
57+ canCreateBranch := perm .CanWrite (unit_model .TypeCode ) && repo .CanCreateBranch ()
58+ if ! canCreateBranch {
3059 ctx .NotFound ("CreateBranch" , nil )
3160 return
3261 }
3362
3463 if ctx .HasError () {
35- ctx .Flash .Error (ctx .GetErrMsg ())
36- ctx .Redirect (ctx .Repo .RepoLink + "/src/" + ctx .Repo .BranchNameSubURL ())
64+ ctx .JSONError (ctx .GetErrMsg ())
3765 return
3866 }
3967
40- if err := repo_service .CreateNewBranch (ctx , ctx .Doer , ctx .Repo .Repository , ctx .Repo .GitRepo , form .SourceBranchName , form .NewBranchName ); err != nil {
41- handleCreateBranchError (ctx , err , form )
68+ if err := repo_service .CreateNewBranch (ctx , ctx .Doer , repo , gitRepo , form .SourceBranchName , form .NewBranchName ); err != nil {
69+ switch {
70+ case git_model .IsErrBranchAlreadyExists (err ) || git .IsErrPushOutOfDate (err ):
71+ ctx .JSONError (ctx .Tr ("repo.branch.branch_already_exists" , form .NewBranchName ))
72+ case git_model .IsErrBranchNameConflict (err ):
73+ e := err .(git_model.ErrBranchNameConflict )
74+ ctx .JSONError (ctx .Tr ("repo.branch.branch_name_conflict" , form .NewBranchName , e .BranchName ))
75+ case git .IsErrPushRejected (err ):
76+ e := err .(* git.ErrPushRejected )
77+ if len (e .Message ) == 0 {
78+ ctx .Flash .Error (ctx .Tr ("repo.editor.push_rejected_no_message" ))
79+ } else {
80+ flashError , err := ctx .RenderToHTML (tplAlertDetails , map [string ]any {
81+ "Message" : ctx .Tr ("repo.editor.push_rejected" ),
82+ "Summary" : ctx .Tr ("repo.editor.push_rejected_summary" ),
83+ "Details" : utils .SanitizeFlashErrorString (e .Message ),
84+ })
85+ if err != nil {
86+ ctx .ServerError ("UpdatePullRequest.HTMLString" , err )
87+ return
88+ }
89+ ctx .JSONError (flashError )
90+ }
91+ default :
92+ ctx .ServerError ("CreateNewBranch" , err )
93+ }
4294 return
4395 }
4496
4597 if err := issues_model .CreateIssueDevLink (ctx , & issues_model.IssueDevLink {
4698 IssueID : issue .ID ,
4799 LinkType : issues_model .IssueDevLinkTypeBranch ,
100+ LinkedRepoID : repo .ID ,
48101 LinkIndex : form .NewBranchName ,
49102 }); err != nil {
50103 ctx .ServerError ("CreateIssueDevLink" , err )
51104 return
52105 }
53106
54107 ctx .Flash .Success (ctx .Tr ("repo.issues.create_branch_from_issue_success" , ctx .Repo .BranchName ))
55- ctx .Redirect (issue .Link ())
108+ ctx .JSONRedirect (issue .Link ())
56109}
0 commit comments