diff options
author | Terence Le Huu Phuong <32878496+tle-huu@users.noreply.github.com> | 2020-05-29 20:16:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-29 19:16:20 +0100 |
commit | 141d52cc0f356776bd6fa538dbda276c3ba44118 (patch) | |
tree | 103a5fe90e0bb23134e49bf784d566e6f9968728 /routers | |
parent | f36104e410b3ed6b269d3b8ffb7f5247125171b6 (diff) | |
download | gitea-141d52cc0f356776bd6fa538dbda276c3ba44118.tar.gz gitea-141d52cc0f356776bd6fa538dbda276c3ba44118.zip |
Add API Endpoint for Branch Creation (#11607)
* [FEATURE] [API] Add Endpoint for Branch Creation
Issue: https://github.com/go-gitea/gitea/issues/11376
This commit introduces an API endpoint for branch creation.
The added route is POST /repos/{owner}/{repo}/branches.
A JSON with the name of the new branch and the name of the old branch is
required as parameters.
Signed-off-by: Terence Le Huu Phuong <terence@qwasar.io>
* Put all the logic into CreateBranch and removed CreateRepoBranch
* - Added the error ErrBranchDoesNotExist in error.go
- Made the CreateNewBranch function return an errBranchDoesNotExist error
when the OldBranch does not exist
- Made the CreateBranch API function checks that the repository is not
empty and that branch exists.
* - Added a resetFixtures helper function in integration_test.go to
fine-tune test env resetting
- Added api test for CreateBranch
- Used resetFixture instead of the more general prepareTestEnv in the
repo_branch_test CreateBranch tests
* Moved the resetFixtures call inside the loop for APICreateBranch function
* Put the prepareTestEnv back in repo_branch_test
* fix import order/sort api branch test
Co-authored-by: zeripath <art27@cantab.net>
Diffstat (limited to 'routers')
-rw-r--r-- | routers/api/v1/api.go | 1 | ||||
-rw-r--r-- | routers/api/v1/repo/branch.go | 90 | ||||
-rw-r--r-- | routers/api/v1/swagger/options.go | 3 |
3 files changed, 94 insertions, 0 deletions
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 0d62b751cc..2eb39f6070 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -665,6 +665,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("", repo.ListBranches) m.Get("/*", context.RepoRefByType(context.RepoRefBranch), repo.GetBranch) m.Delete("/*", reqRepoWriter(models.UnitTypeCode), context.RepoRefByType(context.RepoRefBranch), repo.DeleteBranch) + m.Post("", reqRepoWriter(models.UnitTypeCode), bind(api.CreateBranchRepoOption{}), repo.CreateBranch) }, reqRepoReader(models.UnitTypeCode)) m.Group("/branch_protections", func() { m.Get("", repo.ListBranchProtections) diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 57c74d7dab..90db597ef7 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -182,6 +182,96 @@ func DeleteBranch(ctx *context.APIContext) { ctx.Status(http.StatusNoContent) } +// CreateBranch creates a branch for a user's repository +func CreateBranch(ctx *context.APIContext, opt api.CreateBranchRepoOption) { + // swagger:operation POST /repos/{owner}/{repo}/branches repository repoCreateBranch + // --- + // summary: Create a branch + // consumes: + // - application/json + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // - name: body + // in: body + // schema: + // "$ref": "#/definitions/CreateBranchRepoOption" + // responses: + // "201": + // "$ref": "#/responses/Branch" + // "404": + // description: The old branch does not exist. + // "409": + // description: The branch with the same name already exists. + + if ctx.Repo.Repository.IsEmpty { + ctx.Error(http.StatusNotFound, "", "Git Repository is empty.") + return + } + + if len(opt.OldBranchName) == 0 { + opt.OldBranchName = ctx.Repo.Repository.DefaultBranch + } + + err := repo_module.CreateNewBranch(ctx.User, ctx.Repo.Repository, opt.OldBranchName, opt.BranchName) + + if err != nil { + if models.IsErrBranchDoesNotExist(err) { + ctx.Error(http.StatusNotFound, "", "The old branch does not exist") + } + if models.IsErrTagAlreadyExists(err) { + ctx.Error(http.StatusConflict, "", "The branch with the same tag already exists.") + + } else if models.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) { + ctx.Error(http.StatusConflict, "", "The branch already exists.") + + } else if models.IsErrBranchNameConflict(err) { + ctx.Error(http.StatusConflict, "", "The branch with the same name already exists.") + + } else { + ctx.Error(http.StatusInternalServerError, "CreateRepoBranch", err) + + } + return + } + + branch, err := repo_module.GetBranch(ctx.Repo.Repository, opt.BranchName) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetBranch", err) + return + } + + commit, err := branch.GetCommit() + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetCommit", err) + return + } + + branchProtection, err := ctx.Repo.Repository.GetBranchProtection(branch.Name) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetBranchProtection", err) + return + } + + br, err := convert.ToBranch(ctx.Repo.Repository, branch, commit, branchProtection, ctx.User, ctx.Repo.IsAdmin()) + if err != nil { + ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err) + return + } + + ctx.JSON(http.StatusCreated, br) +} + // ListBranches list all the branches of a repository func ListBranches(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/branches repository repoListBranches diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go index f13dc63864..d9ef05c335 100644 --- a/routers/api/v1/swagger/options.go +++ b/routers/api/v1/swagger/options.go @@ -130,6 +130,9 @@ type swaggerParameterBodies struct { EditReactionOption api.EditReactionOption // in:body + CreateBranchRepoOption api.CreateBranchRepoOption + + // in:body CreateBranchProtectionOption api.CreateBranchProtectionOption // in:body |