aboutsummaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authorTerence Le Huu Phuong <32878496+tle-huu@users.noreply.github.com>2020-05-29 20:16:20 +0200
committerGitHub <noreply@github.com>2020-05-29 19:16:20 +0100
commit141d52cc0f356776bd6fa538dbda276c3ba44118 (patch)
tree103a5fe90e0bb23134e49bf784d566e6f9968728 /routers
parentf36104e410b3ed6b269d3b8ffb7f5247125171b6 (diff)
downloadgitea-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.go1
-rw-r--r--routers/api/v1/repo/branch.go90
-rw-r--r--routers/api/v1/swagger/options.go3
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