@@ -16,6 +16,7 @@ import (
16
16
"code.gitea.io/gitea/modules/charset"
17
17
"code.gitea.io/gitea/modules/git"
18
18
"code.gitea.io/gitea/modules/httplib"
19
+ "code.gitea.io/gitea/modules/log"
19
20
"code.gitea.io/gitea/modules/markup"
20
21
"code.gitea.io/gitea/modules/setting"
21
22
"code.gitea.io/gitea/modules/templates"
@@ -39,26 +40,36 @@ const (
39
40
editorCommitChoiceNewBranch string = "commit-to-new-branch"
40
41
)
41
42
42
- func prepareEditorCommitFormOptions (ctx * context.Context , editorAction string ) {
43
+ func prepareEditorCommitFormOptions (ctx * context.Context , editorAction string ) * context. CommitFormOptions {
43
44
cleanedTreePath := files_service .CleanGitTreePath (ctx .Repo .TreePath )
44
45
if cleanedTreePath != ctx .Repo .TreePath {
45
46
redirectTo := fmt .Sprintf ("%s/%s/%s/%s" , ctx .Repo .RepoLink , editorAction , util .PathEscapeSegments (ctx .Repo .BranchName ), util .PathEscapeSegments (cleanedTreePath ))
46
47
if ctx .Req .URL .RawQuery != "" {
47
48
redirectTo += "?" + ctx .Req .URL .RawQuery
48
49
}
49
50
ctx .Redirect (redirectTo )
50
- return
51
+ return nil
51
52
}
52
53
53
- commitFormBehaviors , err := ctx . Repo .PrepareCommitFormBehaviors ( ctx , ctx .Doer )
54
+ commitFormOptions , err := context . PrepareCommitFormOptions ( ctx , ctx . Doer , ctx . Repo .Repository , ctx . Repo . Permission , ctx .Repo . RefFullName )
54
55
if err != nil {
55
- ctx .ServerError ("PrepareCommitFormBehaviors" , err )
56
- return
56
+ ctx .ServerError ("PrepareCommitFormOptions" , err )
57
+ return nil
58
+ }
59
+
60
+ if commitFormOptions .NeedFork {
61
+ ForkToEdit (ctx )
62
+ return nil
63
+ }
64
+
65
+ if commitFormOptions .WillSubmitToFork && ! commitFormOptions .TargetRepo .CanEnableEditor () {
66
+ ctx .Data ["NotFoundPrompt" ] = ctx .Locale .Tr ("repo.editor.fork_not_editable" )
67
+ ctx .NotFound (nil )
57
68
}
58
69
59
70
ctx .Data ["BranchLink" ] = ctx .Repo .RepoLink + "/src/" + ctx .Repo .RefTypeNameSubURL ()
60
71
ctx .Data ["TreePath" ] = ctx .Repo .TreePath
61
- ctx .Data ["CommitFormBehaviors " ] = commitFormBehaviors
72
+ ctx .Data ["CommitFormOptions " ] = commitFormOptions
62
73
63
74
// for online editor
64
75
ctx .Data ["PreviewableExtensions" ] = strings .Join (markup .PreviewableExtensions (), "," )
@@ -69,33 +80,34 @@ func prepareEditorCommitFormOptions(ctx *context.Context, editorAction string) {
69
80
// form fields
70
81
ctx .Data ["commit_summary" ] = ""
71
82
ctx .Data ["commit_message" ] = ""
72
- ctx .Data ["commit_choice" ] = util .Iif (commitFormBehaviors .CanCommitToBranch , editorCommitChoiceDirect , editorCommitChoiceNewBranch )
73
- ctx .Data ["new_branch_name" ] = getUniquePatchBranchName (ctx , ctx .Doer .LowerName , ctx . Repo . Repository )
83
+ ctx .Data ["commit_choice" ] = util .Iif (commitFormOptions .CanCommitToBranch , editorCommitChoiceDirect , editorCommitChoiceNewBranch )
84
+ ctx .Data ["new_branch_name" ] = getUniquePatchBranchName (ctx , ctx .Doer .LowerName , commitFormOptions . TargetRepo )
74
85
ctx .Data ["last_commit" ] = ctx .Repo .CommitID
86
+ return commitFormOptions
75
87
}
76
88
77
89
func prepareTreePathFieldsAndPaths (ctx * context.Context , treePath string ) {
78
90
// show the tree path fields in the "breadcrumb" and help users to edit the target tree path
79
91
ctx .Data ["TreeNames" ], ctx .Data ["TreePaths" ] = getParentTreeFields (treePath )
80
92
}
81
93
82
- type parsedEditorCommitForm [T any ] struct {
83
- form T
84
- commonForm * forms.CommitCommonForm
85
- CommitFormBehaviors * context.CommitFormBehaviors
86
- TargetBranchName string
87
- GitCommitter * files_service.IdentityOptions
94
+ type preparedEditorCommitForm [T any ] struct {
95
+ form T
96
+ commonForm * forms.CommitCommonForm
97
+ CommitFormOptions * context.CommitFormOptions
98
+ TargetBranchName string
99
+ GitCommitter * files_service.IdentityOptions
88
100
}
89
101
90
- func (f * parsedEditorCommitForm [T ]) GetCommitMessage (defaultCommitMessage string ) string {
102
+ func (f * preparedEditorCommitForm [T ]) GetCommitMessage (defaultCommitMessage string ) string {
91
103
commitMessage := util .IfZero (strings .TrimSpace (f .commonForm .CommitSummary ), defaultCommitMessage )
92
104
if body := strings .TrimSpace (f .commonForm .CommitMessage ); body != "" {
93
105
commitMessage += "\n \n " + body
94
106
}
95
107
return commitMessage
96
108
}
97
109
98
- func parseEditorCommitSubmittedForm [T forms.CommitCommonFormInterface ](ctx * context.Context ) * parsedEditorCommitForm [T ] {
110
+ func prepareEditorCommitSubmittedForm [T forms.CommitCommonFormInterface ](ctx * context.Context ) * preparedEditorCommitForm [T ] {
99
111
form := web .GetForm (ctx ).(T )
100
112
if ctx .HasError () {
101
113
ctx .JSONError (ctx .GetErrMsg ())
@@ -105,15 +117,20 @@ func parseEditorCommitSubmittedForm[T forms.CommitCommonFormInterface](ctx *cont
105
117
commonForm := form .GetCommitCommonForm ()
106
118
commonForm .TreePath = files_service .CleanGitTreePath (commonForm .TreePath )
107
119
108
- commitFormBehaviors , err := ctx . Repo .PrepareCommitFormBehaviors ( ctx , ctx .Doer )
120
+ commitFormOptions , err := context . PrepareCommitFormOptions ( ctx , ctx . Doer , ctx . Repo .Repository , ctx . Repo . Permission , ctx .Repo . RefFullName )
109
121
if err != nil {
110
- ctx .ServerError ("PrepareCommitFormBehaviors" , err )
122
+ ctx .ServerError ("PrepareCommitFormOptions" , err )
123
+ return nil
124
+ }
125
+ if commitFormOptions .NeedFork {
126
+ // It shouldn't happen, because we should have done the checks in the "GET" request. But just in case.
127
+ ctx .JSONError (ctx .Locale .TrString ("error.not_found" ))
111
128
return nil
112
129
}
113
130
114
131
// check commit behavior
115
132
targetBranchName := util .Iif (commonForm .CommitChoice == editorCommitChoiceNewBranch , commonForm .NewBranchName , ctx .Repo .BranchName )
116
- if targetBranchName == ctx .Repo .BranchName && ! commitFormBehaviors .CanCommitToBranch {
133
+ if targetBranchName == ctx .Repo .BranchName && ! commitFormOptions .CanCommitToBranch {
117
134
ctx .JSONError (ctx .Tr ("repo.editor.cannot_commit_to_protected_branch" , targetBranchName ))
118
135
return nil
119
136
}
@@ -125,28 +142,38 @@ func parseEditorCommitSubmittedForm[T forms.CommitCommonFormInterface](ctx *cont
125
142
return nil
126
143
}
127
144
128
- return & parsedEditorCommitForm [T ]{
129
- form : form ,
130
- commonForm : commonForm ,
131
- CommitFormBehaviors : commitFormBehaviors ,
132
- TargetBranchName : targetBranchName ,
133
- GitCommitter : gitCommitter ,
145
+ fromBaseBranch := ctx .FormString ("from_base_branch" )
146
+ if fromBaseBranch != "" {
147
+ err = editorPushBranchToForkedRepository (ctx , ctx .Doer , ctx .Repo .Repository .BaseRepo , fromBaseBranch , ctx .Repo .Repository , ctx .Repo .RefFullName .BranchName ())
148
+ if err != nil {
149
+ log .Error ("Unable to editorPushBranchToForkedRepository: %v" , err )
150
+ ctx .JSONError (ctx .Tr ("repo.editor.fork_failed_to_push_branch" , targetBranchName ))
151
+ return nil
152
+ }
153
+ }
154
+
155
+ return & preparedEditorCommitForm [T ]{
156
+ form : form ,
157
+ commonForm : commonForm ,
158
+ CommitFormOptions : commitFormOptions ,
159
+ TargetBranchName : targetBranchName ,
160
+ GitCommitter : gitCommitter ,
134
161
}
135
162
}
136
163
137
164
// redirectForCommitChoice redirects after committing the edit to a branch
138
- func redirectForCommitChoice [T any ](ctx * context.Context , parsed * parsedEditorCommitForm [T ], treePath string ) {
165
+ func redirectForCommitChoice [T any ](ctx * context.Context , parsed * preparedEditorCommitForm [T ], treePath string ) {
139
166
if parsed .commonForm .CommitChoice == editorCommitChoiceNewBranch {
140
167
// Redirect to a pull request when possible
141
168
redirectToPullRequest := false
142
169
repo , baseBranch , headBranch := ctx .Repo .Repository , ctx .Repo .BranchName , parsed .TargetBranchName
143
- if repo .UnitEnabled (ctx , unit .TypePullRequests ) {
144
- redirectToPullRequest = true
145
- } else if parsed .CommitFormBehaviors .CanCreateBasePullRequest {
170
+ if ctx .Repo .Repository .IsFork && parsed .CommitFormOptions .CanCreateBasePullRequest {
146
171
redirectToPullRequest = true
147
172
baseBranch = repo .BaseRepo .DefaultBranch
148
173
headBranch = repo .Owner .Name + "/" + repo .Name + ":" + headBranch
149
174
repo = repo .BaseRepo
175
+ } else if repo .UnitEnabled (ctx , unit .TypePullRequests ) {
176
+ redirectToPullRequest = true
150
177
}
151
178
if redirectToPullRequest {
152
179
ctx .JSONRedirect (repo .Link () + "/compare/" + util .PathEscapeSegments (baseBranch ) + "..." + util .PathEscapeSegments (headBranch ))
@@ -268,7 +295,7 @@ func EditFile(ctx *context.Context) {
268
295
func EditFilePost (ctx * context.Context ) {
269
296
editorAction := ctx .PathParam ("editor_action" )
270
297
isNewFile := editorAction == "_new"
271
- parsed := parseEditorCommitSubmittedForm [* forms.EditRepoFileForm ](ctx )
298
+ parsed := prepareEditorCommitSubmittedForm [* forms.EditRepoFileForm ](ctx )
272
299
if ctx .Written () {
273
300
return
274
301
}
@@ -327,7 +354,7 @@ func DeleteFile(ctx *context.Context) {
327
354
328
355
// DeleteFilePost response for deleting file
329
356
func DeleteFilePost (ctx * context.Context ) {
330
- parsed := parseEditorCommitSubmittedForm [* forms.DeleteRepoFileForm ](ctx )
357
+ parsed := prepareEditorCommitSubmittedForm [* forms.DeleteRepoFileForm ](ctx )
331
358
if ctx .Written () {
332
359
return
333
360
}
@@ -360,18 +387,18 @@ func DeleteFilePost(ctx *context.Context) {
360
387
361
388
func UploadFile (ctx * context.Context ) {
362
389
ctx .Data ["PageIsUpload" ] = true
363
- upload .AddUploadContext (ctx , "repo" )
364
390
prepareTreePathFieldsAndPaths (ctx , ctx .Repo .TreePath )
365
-
366
- prepareEditorCommitFormOptions (ctx , "_upload" )
391
+ opts := prepareEditorCommitFormOptions (ctx , "_upload" )
367
392
if ctx .Written () {
368
393
return
369
394
}
395
+ upload .AddUploadContextForRepo (ctx , opts .TargetRepo )
396
+
370
397
ctx .HTML (http .StatusOK , tplUploadFile )
371
398
}
372
399
373
400
func UploadFilePost (ctx * context.Context ) {
374
- parsed := parseEditorCommitSubmittedForm [* forms.UploadRepoFileForm ](ctx )
401
+ parsed := prepareEditorCommitSubmittedForm [* forms.UploadRepoFileForm ](ctx )
375
402
if ctx .Written () {
376
403
return
377
404
}
0 commit comments