@@ -400,12 +400,11 @@ func CreatePullRequest(ctx *context.APIContext) {
400400 )
401401
402402 // Get repo/branch information
403- //headRepo, headGitRepo, compareInfo, baseBranch, headBranch := parseCompareInfo(ctx, form)
404- compareResult := parseCompareInfo (ctx , form )
403+ compareResult , closer := parseCompareInfo (ctx , form )
405404 if ctx .Written () {
406405 return
407406 }
408- defer compareResult . headGitRepo . Close ()
407+ defer closer ()
409408
410409 if ! compareResult .baseRef .IsBranch () || ! compareResult .headRef .IsBranch () {
411410 ctx .Error (http .StatusUnprocessableEntity , "BaseHeadInvalidRefType" , "Invalid PullRequest: base and head must be branches" )
@@ -1096,7 +1095,8 @@ type parseCompareInfoResult struct {
10961095 headRef git.RefName
10971096}
10981097
1099- func parseCompareInfo (ctx * context.APIContext , form api.CreatePullRequestOption ) * parseCompareInfoResult {
1098+ // parseCompareInfo returns non-nil if it succeeds, it always writes to the context and returns nil if it fails
1099+ func parseCompareInfo (ctx * context.APIContext , form api.CreatePullRequestOption ) (result * parseCompareInfoResult , closer func () error ) {
11001100 var err error
11011101 // Get compared branches information
11021102 // format: <base branch>...[<head repo>:]<head branch>
@@ -1123,11 +1123,11 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
11231123 } else {
11241124 ctx .Error (http .StatusInternalServerError , "GetUserByName" , err )
11251125 }
1126- return nil
1126+ return nil , nil
11271127 }
11281128 } else {
11291129 ctx .NotFound ()
1130- return nil
1130+ return nil , nil
11311131 }
11321132
11331133 isSameRepo := ctx .Repo .Owner .ID == headUser .ID
@@ -1138,14 +1138,14 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
11381138 err = baseRepo .GetBaseRepo (ctx )
11391139 if err != nil {
11401140 ctx .Error (http .StatusInternalServerError , "GetBaseRepo" , err )
1141- return nil
1141+ return nil , nil
11421142 }
11431143
11441144 // Check if baseRepo's base repository is the same as headUser's repository.
11451145 if baseRepo .BaseRepo == nil || baseRepo .BaseRepo .OwnerID != headUser .ID {
11461146 log .Trace ("parseCompareInfo[%d]: does not have fork or in same repository" , baseRepo .ID )
11471147 ctx .NotFound ("GetBaseRepo" )
1148- return nil
1148+ return nil , nil
11491149 }
11501150 // Assign headRepo so it can be used below.
11511151 headRepo = baseRepo .BaseRepo
@@ -1154,44 +1154,45 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
11541154 var headGitRepo * git.Repository
11551155 if isSameRepo {
11561156 headRepo = ctx .Repo .Repository
1157- // FIXME: it is not right, the caller will close this "ctx.Repo.GitRepo",
1158- // but there could still be other operations on it later
11591157 headGitRepo = ctx .Repo .GitRepo
1158+ closer = func () error { return nil } // no need to close the head repo because it shares the base repo
11601159 } else {
11611160 headGitRepo , err = gitrepo .OpenRepository (ctx , headRepo )
11621161 if err != nil {
11631162 ctx .Error (http .StatusInternalServerError , "OpenRepository" , err )
1164- return nil
1163+ return nil , nil
11651164 }
1165+ closer = headGitRepo .Close
11661166 }
1167+ defer func () {
1168+ if result == nil && ! isSameRepo {
1169+ _ = headGitRepo .Close ()
1170+ }
1171+ }()
11671172
11681173 // user should have permission to read baseRepo's codes and pulls, NOT headRepo's
11691174 permBase , err := access_model .GetUserRepoPermission (ctx , baseRepo , ctx .Doer )
11701175 if err != nil {
1171- headGitRepo .Close ()
11721176 ctx .Error (http .StatusInternalServerError , "GetUserRepoPermission" , err )
1173- return nil
1177+ return nil , nil
11741178 }
11751179
11761180 if ! permBase .CanReadIssuesOrPulls (true ) || ! permBase .CanRead (unit .TypeCode ) {
11771181 log .Trace ("Permission Denied: User %-v cannot create/read pull requests or cannot read code in Repo %-v\n User in baseRepo has Permissions: %-+v" , ctx .Doer , baseRepo , permBase )
1178- headGitRepo .Close ()
11791182 ctx .NotFound ("Can't read pulls or can't read UnitTypeCode" )
1180- return nil
1183+ return nil , nil
11811184 }
11821185
11831186 // user should have permission to read headrepo's codes
11841187 permHead , err := access_model .GetUserRepoPermission (ctx , headRepo , ctx .Doer )
11851188 if err != nil {
1186- headGitRepo .Close ()
11871189 ctx .Error (http .StatusInternalServerError , "GetUserRepoPermission" , err )
1188- return nil
1190+ return nil , nil
11891191 }
11901192 if ! permHead .CanRead (unit .TypeCode ) {
11911193 log .Trace ("Permission Denied: User: %-v cannot read code in Repo: %-v\n User in headRepo has Permissions: %-+v" , ctx .Doer , headRepo , permHead )
1192- headGitRepo .Close ()
11931194 ctx .NotFound ("Can't read headRepo UnitTypeCode" )
1194- return nil
1195+ return nil , nil
11951196 }
11961197
11971198 baseRef := ctx .Repo .GitRepo .UnstableGuessRefByShortName (baseRefToGuess )
@@ -1203,19 +1204,18 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
12031204 headRefValid := headRef .IsBranch () || headRef .IsTag () || git .IsStringLikelyCommitID (git .ObjectFormatFromName (headRepo .ObjectFormatName ), headRef .ShortName ())
12041205 // Check if base&head ref are valid.
12051206 if ! baseRefValid || ! headRefValid {
1206- headGitRepo .Close ()
12071207 ctx .NotFound ()
1208- return nil
1208+ return nil , nil
12091209 }
12101210
12111211 compareInfo , err := headGitRepo .GetCompareInfo (repo_model .RepoPath (baseRepo .Owner .Name , baseRepo .Name ), baseRef .ShortName (), headRef .ShortName (), false , false )
12121212 if err != nil {
1213- headGitRepo .Close ()
12141213 ctx .Error (http .StatusInternalServerError , "GetCompareInfo" , err )
1215- return nil
1214+ return nil , nil
12161215 }
12171216
1218- return & parseCompareInfoResult {headRepo : headRepo , headGitRepo : headGitRepo , compareInfo : compareInfo , baseRef : baseRef , headRef : headRef }
1217+ result = & parseCompareInfoResult {headRepo : headRepo , headGitRepo : headGitRepo , compareInfo : compareInfo , baseRef : baseRef , headRef : headRef }
1218+ return result , closer
12191219}
12201220
12211221// UpdatePullRequest merge PR's baseBranch into headBranch
0 commit comments