@@ -30,6 +30,7 @@ import (
3030 "code.gitea.io/gitea/modules/timeutil"
3131 "code.gitea.io/gitea/modules/web"
3232 "code.gitea.io/gitea/routers/api/v1/utils"
33+ "code.gitea.io/gitea/routers/common"
3334 asymkey_service "code.gitea.io/gitea/services/asymkey"
3435 "code.gitea.io/gitea/services/automerge"
3536 "code.gitea.io/gitea/services/context"
@@ -413,7 +414,7 @@ func CreatePullRequest(ctx *context.APIContext) {
413414 )
414415
415416 // Get repo/branch information
416- compareResult , closer := parseCompareInfo (ctx , form )
417+ compareResult , closer := parseCompareInfo (ctx , form . Base + ".." + form . Head )
417418 if ctx .Written () {
418419 return
419420 }
@@ -1065,61 +1066,76 @@ type parseCompareInfoResult struct {
10651066}
10661067
10671068// parseCompareInfo returns non-nil if it succeeds, it always writes to the context and returns nil if it fails
1068- func parseCompareInfo (ctx * context.APIContext , form api.CreatePullRequestOption ) (result * parseCompareInfoResult , closer func ()) {
1069- var err error
1070- // Get compared branches information
1071- // format: <base branch>...[<head repo>:]<head branch>
1072- // base<-head: master...head:feature
1073- // same repo: master...feature
1069+ func parseCompareInfo (ctx * context.APIContext , compareParam string ) (result * parseCompareInfoResult , closer func ()) {
10741070 baseRepo := ctx .Repo .Repository
1075- baseRefToGuess := form .Base
1076-
1077- headUser := ctx .Repo .Owner
1078- headRefToGuess := form .Head
1079- if headInfos := strings .Split (form .Head , ":" ); len (headInfos ) == 1 {
1080- // If there is no head repository, it means pull request between same repository.
1081- // Do nothing here because the head variables have been assigned above.
1082- } else if len (headInfos ) == 2 {
1083- // There is a head repository (the head repository could also be the same base repo)
1084- headRefToGuess = headInfos [1 ]
1085- headUser , err = user_model .GetUserByName (ctx , headInfos [0 ])
1086- if err != nil {
1087- if user_model .IsErrUserNotExist (err ) {
1088- ctx .APIErrorNotFound ("GetUserByName" )
1089- } else {
1090- ctx .APIErrorInternal (err )
1091- }
1092- return nil , nil
1093- }
1094- } else {
1071+ compareReq , err := common .ParseCompareRouterParam (baseRepo , compareParam )
1072+ if err != nil {
10951073 ctx .APIErrorNotFound ()
10961074 return nil , nil
10971075 }
10981076
1099- isSameRepo := ctx .Repo .Owner .ID == headUser .ID
1100-
1101- // Check if current user has fork of repository or in the same repository.
1102- headRepo := repo_model .GetForkedRepo (ctx , headUser .ID , baseRepo .ID )
1103- if headRepo == nil && ! isSameRepo {
1104- err = baseRepo .GetBaseRepo (ctx )
1105- if err != nil {
1106- ctx .APIErrorInternal (err )
1077+ var headRepo * repo_model.Repository
1078+ if compareReq .HeadOwner == "" {
1079+ if compareReq .HeadRepoName == "" {
1080+ headRepo = ctx .Repo .Repository
1081+ } else {
1082+ ctx .APIErrorNotFound ()
11071083 return nil , nil
11081084 }
1109-
1110- // Check if baseRepo's base repository is the same as headUser's repository.
1111- if baseRepo .BaseRepo == nil || baseRepo .BaseRepo .OwnerID != headUser .ID {
1112- log .Trace ("parseCompareInfo[%d]: does not have fork or in same repository" , baseRepo .ID )
1113- ctx .APIErrorNotFound ("GetBaseRepo" )
1114- return nil , nil
1085+ } else {
1086+ var headUser * user_model.User
1087+ if compareReq .HeadOwner == ctx .Repo .Owner .Name {
1088+ headUser = ctx .Repo .Owner
1089+ } else {
1090+ headUser , err = user_model .GetUserByName (ctx , compareReq .HeadOwner )
1091+ if err != nil {
1092+ if user_model .IsErrUserNotExist (err ) {
1093+ ctx .APIErrorNotFound ("GetUserByName" )
1094+ } else {
1095+ ctx .APIErrorInternal (err )
1096+ }
1097+ return nil , nil
1098+ }
1099+ }
1100+ if compareReq .HeadRepoName == "" {
1101+ headRepo = repo_model .GetForkedRepo (ctx , headUser .ID , baseRepo .ID )
1102+ if headRepo == nil && headUser .ID != baseRepo .OwnerID {
1103+ err = baseRepo .GetBaseRepo (ctx )
1104+ if err != nil {
1105+ ctx .APIErrorInternal (err )
1106+ return nil , nil
1107+ }
1108+
1109+ // Check if baseRepo's base repository is the same as headUser's repository.
1110+ if baseRepo .BaseRepo == nil || baseRepo .BaseRepo .OwnerID != headUser .ID {
1111+ log .Trace ("parseCompareInfo[%d]: does not have fork or in same repository" , baseRepo .ID )
1112+ ctx .APIErrorNotFound ("GetBaseRepo" )
1113+ return nil , nil
1114+ }
1115+ // Assign headRepo so it can be used below.
1116+ headRepo = baseRepo .BaseRepo
1117+ }
1118+ } else {
1119+ if compareReq .HeadOwner == ctx .Repo .Owner .Name && compareReq .HeadRepoName == ctx .Repo .Repository .Name {
1120+ headRepo = ctx .Repo .Repository
1121+ } else {
1122+ headRepo , err = repo_model .GetRepositoryByName (ctx , headUser .ID , compareReq .HeadRepoName )
1123+ if err != nil {
1124+ if repo_model .IsErrRepoNotExist (err ) {
1125+ ctx .APIErrorNotFound ("GetRepositoryByName" )
1126+ } else {
1127+ ctx .APIErrorInternal (err )
1128+ }
1129+ return nil , nil
1130+ }
1131+ }
11151132 }
1116- // Assign headRepo so it can be used below.
1117- headRepo = baseRepo .BaseRepo
11181133 }
11191134
1135+ isSameRepo := baseRepo .ID == headRepo .ID
1136+
11201137 var headGitRepo * git.Repository
11211138 if isSameRepo {
1122- headRepo = ctx .Repo .Repository
11231139 headGitRepo = ctx .Repo .GitRepo
11241140 closer = func () {} // no need to close the head repo because it shares the base repo
11251141 } else {
@@ -1162,10 +1178,10 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
11621178 return nil , nil
11631179 }
11641180
1165- baseRef := ctx .Repo .GitRepo .UnstableGuessRefByShortName (baseRefToGuess )
1166- headRef := headGitRepo .UnstableGuessRefByShortName (headRefToGuess )
1181+ baseRef := ctx .Repo .GitRepo .UnstableGuessRefByShortName (compareReq . BaseOriRef )
1182+ headRef := headGitRepo .UnstableGuessRefByShortName (compareReq . HeadOriRef )
11671183
1168- log .Trace ("Repo path: %q, base ref: %q->%q, head ref: %q->%q" , ctx .Repo .Repository .RelativePath (), baseRefToGuess , baseRef , headRefToGuess , headRef )
1184+ log .Trace ("Repo path: %q, base ref: %q->%q, head ref: %q->%q" , ctx .Repo .Repository .RelativePath (), compareReq . BaseOriRef , baseRef , compareReq . HeadOriRef , headRef )
11691185
11701186 baseRefValid := baseRef .IsBranch () || baseRef .IsTag () || git .IsStringLikelyCommitID (git .ObjectFormatFromName (ctx .Repo .Repository .ObjectFormatName ), baseRef .ShortName ())
11711187 headRefValid := headRef .IsBranch () || headRef .IsTag () || git .IsStringLikelyCommitID (git .ObjectFormatFromName (headRepo .ObjectFormatName ), headRef .ShortName ())
0 commit comments