Merge pull request '[API]Add:file_commit/{filepath}' (#28) from wonderful/gitea-1156:develop into develop

This commit is contained in:
yystopf 2021-12-06 14:02:49 +08:00
commit 18037c8109
5 changed files with 268 additions and 0 deletions

View File

@ -191,6 +191,11 @@ func (c *Commit) CommitsByRange(page, pageSize int) (*list.List, error) {
return c.repo.commitsByRange(c.ID, page, pageSize)
}
// CommitsByFileAndRange returns the specific page page commits before current revision and file, every page's number default by CommitsRangeSize
func (c *Commit) CommitsByFileAndRange(file string, page, pageSize int) (*list.List, error) {
return c.repo.CommitsByFileAndRange(c.ID.String(), file, page)
}
// CommitsBefore returns all the commits before current revision
func (c *Commit) CommitsBefore() (*list.List, error) {
return c.repo.getCommitsBefore(c.ID)

View File

@ -768,6 +768,9 @@ func Routes() *web.Route {
m.Group("/count", func() {
m.Get("", viewfile.GetCommitCount) //****
})
m.Group("/file_commits", func() {
m.Get("/*", repo.GetFileAllCommits)
})
m.Group("/hooks", func() {
m.Combo("").Get(repo.ListHooks).
Post(bind(api.CreateHookOption{}), repo.CreateHook)

View File

@ -396,3 +396,142 @@ func GetCommitsCount(ctx *context.APIContext) {
}
ctx.JSON(http.StatusOK, &ctx.Repo)
}
// GetFileAllCommits get all commits by path on a repository
func GetFileAllCommits(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/file_commits/{filepath} repository repoGetFileAllCommits
// ---
// summary: Get a list of all commits by filepath from a repository ***
// 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: filepath
// in: path
// description: filepath of the file to get
// type: string
// required: true
// - name: sha
// in: query
// description: SHA or branch to start listing commits from (usually 'master')
// type: string
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results
// type: integer
// responses:
// "200":
// "$ref": "#/responses/FileCommitList"
// "404":
// "$ref": "#/responses/notFound"
// "409":
// "$ref": "#/responses/EmptyRepository"
if ctx.Repo.Repository.IsEmpty {
ctx.JSON(http.StatusConflict, api.APIError{
Message: "Git Repository is empty",
URL: setting.API.SwaggerURL,
})
return
}
gitRepo, err := git.OpenRepository(ctx.Repo.Repository.RepoPath())
if err != nil {
ctx.Error(http.StatusInternalServerError, "Get the GitRepo", err)
return
}
defer gitRepo.Close()
listOptions := utils.GetListOptions(ctx)
if listOptions.Page <= 0 {
listOptions.Page = 1
}
if listOptions.PageSize > setting.Git.CommitsRangeSize {
listOptions.PageSize = setting.Git.CommitsRangeSize
}
sha := ctx.Query("sha")
treePath := ctx.Params(":*")
var baseCommit *git.Commit
var commitsCountTotal int64
if len(sha) == 0 {
head, err := gitRepo.GetHEADBranch()
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetHeadBranch", err)
return
}
baseCommit, err = gitRepo.GetBranchCommit(head.Name)
if err != nil {
ctx.Error(http.StatusInternalServerError, "Getcommit ", err)
return
}
commitsCountTotal, err = git.CommitsCountFiles(gitRepo.Path, []string{head.Name}, []string{treePath}) // get th commmit count by file
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommmisCountFiles", err)
return
}
} else {
baseCommit, err = gitRepo.GetCommit(sha)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
return
}
commitsCountTotal, err = git.CommitsCountFiles(gitRepo.Path, []string{sha}, []string{treePath})
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommitsCountFiles", err)
return
}
}
pageCount := int(math.Ceil(float64(commitsCountTotal) / float64(listOptions.PageSize)))
commits, err := baseCommit.CommitsByFileAndRange(treePath, listOptions.Page, listOptions.PageSize)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommitByFileAndRange", err)
return
}
userCache := make(map[string]*models.User)
apiCommits := make([]*api.Commit, commits.Len())
i := 0
for commitPointer := commits.Front(); commitPointer != nil; commitPointer = commitPointer.Next() {
commit := commitPointer.Value.(*git.Commit)
// Create json struct
apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, commit, userCache)
if err != nil {
ctx.Error(http.StatusInternalServerError, "toCommit", err)
return
}
i++
}
// kept for backwards compatibility
ctx.Header().Set("X-Page", strconv.Itoa(listOptions.Page))
ctx.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize))
ctx.Header().Set("X-Total", strconv.FormatInt(commitsCountTotal, 10))
ctx.Header().Set("X-PageCount", strconv.Itoa(pageCount))
ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < pageCount))
ctx.SetLinkHeader(int(commitsCountTotal), listOptions.PageSize)
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", commitsCountTotal))
ctx.JSON(http.StatusOK, apiCommits)
}

View File

@ -283,6 +283,28 @@ type swaggerCommitList struct {
Body []api.Commit `json:"body"`
}
// FileCommitList
// swagger:response FileCommitList
type swaggerFileCommitList struct {
// The current page
Page int `json:"X-Page"`
// Commits per page
PerPage int `json:"X-PerPage"`
// Total commit count
Total int `json:"X-Total"`
// Total number of pages
PageCount int `json:"X-PageCount"`
// True if there is another page
HasMore bool `json:"X-HasMore"`
// in: body
Body []api.Commit `json:"body"`
}
// EmptyRepository
// swagger:response EmptyRepository
type swaggerEmptyRepository struct {

View File

@ -3706,6 +3706,70 @@
}
}
},
"/repos/{owner}/{repo}/file_commits/{filepath}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Get a list of all commits by filepath from a repository ***",
"operationId": "repoGetFileAllCommits",
"parameters": [
{
"type": "string",
"description": "owner of the repo",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repo",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "string",
"description": "filepath of the file to get",
"name": "filepath",
"in": "path",
"required": true
},
{
"type": "string",
"description": "SHA or branch to start listing commits from (usually 'master')",
"name": "sha",
"in": "query"
},
{
"type": "integer",
"description": "page number of results to return (1-based)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "page size of results",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"$ref": "#/responses/FileCommitList"
},
"404": {
"$ref": "#/responses/notFound"
},
"409": {
"$ref": "#/responses/EmptyRepository"
}
}
}
},
"/repos/{owner}/{repo}/find": {
"get": {
"produces": [
@ -18384,6 +18448,41 @@
"$ref": "#/definitions/APIError"
}
},
"FileCommitList": {
"description": "FileCommitList",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Commit"
}
},
"headers": {
"X-HasMore": {
"type": "boolean",
"description": "True if there is another page"
},
"X-Page": {
"type": "integer",
"format": "int64",
"description": "The current page"
},
"X-PageCount": {
"type": "integer",
"format": "int64",
"description": "Total number of pages"
},
"X-PerPage": {
"type": "integer",
"format": "int64",
"description": "Commits per page"
},
"X-Total": {
"type": "integer",
"format": "int64",
"description": "Total commit count"
}
}
},
"FileDeleteResponse": {
"description": "FileDeleteResponse",
"schema": {