code.gitea.io/gitea@v1.21.7/routers/api/v1/repo/patch.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package repo 5 6 import ( 7 "net/http" 8 "time" 9 10 "code.gitea.io/gitea/models" 11 git_model "code.gitea.io/gitea/models/git" 12 repo_model "code.gitea.io/gitea/models/repo" 13 "code.gitea.io/gitea/modules/context" 14 "code.gitea.io/gitea/modules/git" 15 api "code.gitea.io/gitea/modules/structs" 16 "code.gitea.io/gitea/modules/web" 17 "code.gitea.io/gitea/services/repository/files" 18 ) 19 20 // ApplyDiffPatch handles API call for applying a patch 21 func ApplyDiffPatch(ctx *context.APIContext) { 22 // swagger:operation POST /repos/{owner}/{repo}/diffpatch repository repoApplyDiffPatch 23 // --- 24 // summary: Apply diff patch to repository 25 // consumes: 26 // - application/json 27 // produces: 28 // - application/json 29 // parameters: 30 // - name: owner 31 // in: path 32 // description: owner of the repo 33 // type: string 34 // required: true 35 // - name: repo 36 // in: path 37 // description: name of the repo 38 // type: string 39 // required: true 40 // - name: body 41 // in: body 42 // required: true 43 // schema: 44 // "$ref": "#/definitions/UpdateFileOptions" 45 // responses: 46 // "200": 47 // "$ref": "#/responses/FileResponse" 48 // "404": 49 // "$ref": "#/responses/notFound" 50 apiOpts := web.GetForm(ctx).(*api.ApplyDiffPatchFileOptions) 51 52 opts := &files.ApplyDiffPatchOptions{ 53 Content: apiOpts.Content, 54 SHA: apiOpts.SHA, 55 Message: apiOpts.Message, 56 OldBranch: apiOpts.BranchName, 57 NewBranch: apiOpts.NewBranchName, 58 Committer: &files.IdentityOptions{ 59 Name: apiOpts.Committer.Name, 60 Email: apiOpts.Committer.Email, 61 }, 62 Author: &files.IdentityOptions{ 63 Name: apiOpts.Author.Name, 64 Email: apiOpts.Author.Email, 65 }, 66 Dates: &files.CommitDateOptions{ 67 Author: apiOpts.Dates.Author, 68 Committer: apiOpts.Dates.Committer, 69 }, 70 Signoff: apiOpts.Signoff, 71 } 72 if opts.Dates.Author.IsZero() { 73 opts.Dates.Author = time.Now() 74 } 75 if opts.Dates.Committer.IsZero() { 76 opts.Dates.Committer = time.Now() 77 } 78 79 if opts.Message == "" { 80 opts.Message = "apply-patch" 81 } 82 83 if !canWriteFiles(ctx, apiOpts.BranchName) { 84 ctx.Error(http.StatusInternalServerError, "ApplyPatch", repo_model.ErrUserDoesNotHaveAccessToRepo{ 85 UserID: ctx.Doer.ID, 86 RepoName: ctx.Repo.Repository.LowerName, 87 }) 88 return 89 } 90 91 fileResponse, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, opts) 92 if err != nil { 93 if models.IsErrUserCannotCommit(err) || models.IsErrFilePathProtected(err) { 94 ctx.Error(http.StatusForbidden, "Access", err) 95 return 96 } 97 if git_model.IsErrBranchAlreadyExists(err) || models.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) || 98 models.IsErrFilePathInvalid(err) || models.IsErrRepoFileAlreadyExists(err) { 99 ctx.Error(http.StatusUnprocessableEntity, "Invalid", err) 100 return 101 } 102 if git_model.IsErrBranchNotExist(err) || git.IsErrBranchNotExist(err) { 103 ctx.Error(http.StatusNotFound, "BranchDoesNotExist", err) 104 return 105 } 106 ctx.Error(http.StatusInternalServerError, "ApplyPatch", err) 107 } else { 108 ctx.JSON(http.StatusCreated, fileResponse) 109 } 110 }