add:sort the branches by time

This commit is contained in:
wonderful 2021-09-07 11:30:02 +08:00
parent 86fb4bb8d8
commit fdfe572500
4 changed files with 322 additions and 12 deletions

View File

@ -20,6 +20,7 @@ type Identity struct {
type CommitMeta struct {
URL string `json:"url"`
SHA string `json:"sha"`
}
// CommitUser contains information of a user in the context of a commit.
@ -38,6 +39,7 @@ type RepoCommit struct {
}
// Commit contains information generated from a Git commit.
type SortCommit []Commit
type Commit struct {
*CommitMeta
HTMLURL string `json:"html_url"`
@ -45,8 +47,18 @@ type Commit struct {
Author *User `json:"author"`
Committer *User `json:"committer"`
Parents []*CommitMeta `json:"parents"`
CommitDate string `json:"commit_date"`
}
type CommitsSlice struct{
CommitDate string `json:"commit_date"`
Commits []Commit
}
func (s SortCommit) Len() int {return len(s)}
func (s SortCommit) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s SortCommit) Less(i, j int) bool { return s[i].CommitDate > s[j].CommitDate}
// CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE
type CommitDateOptions struct {
// swagger:strfmt date-time

View File

@ -704,7 +704,7 @@ func RegisterRoutes(m *macaron.Macaron) {
// alter on 2021/01/15
m.Get("", viewfile.Readme) // reqRepoReader(models.UnitTypeCode),
}, reqToken())
})
m.Group("/count", func() {
m.Get("", viewfile.CommitCount) //****
@ -795,6 +795,7 @@ func RegisterRoutes(m *macaron.Macaron) {
Post(reqToken(), reqRepoReader(models.UnitTypeCode), bind(api.CreateForkOption{}), repo.CreateFork)
m.Group("/branches", func() {
m.Get("", repo.ListBranches)
m.Get("/branches_slice", repo.ListBranchesSlice)
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)
@ -951,11 +952,13 @@ func RegisterRoutes(m *macaron.Macaron) {
}, reqRepoReader(models.UnitTypeCode))
m.Group("/commits", func() {
m.Get("", repo.GetAllCommits)
m.Group("/:ref", func() {
m.Get("/status", repo.GetCombinedCommitStatusByRef)
m.Get("/statuses", repo.GetCommitStatusesByRef)
})
}, reqRepoReader(models.UnitTypeCode))
m.Get("/commits_slice", repo.GetAllCommitsSliceByTime)
m.Group("/git", func() {
m.Group("/commits", func() {
m.Get("/:sha", repo.GetSingleCommit)

View File

@ -9,18 +9,19 @@ import (
"fmt"
"math"
"net/http"
"sort"
"strconv"
"time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/gitgraph"
"code.gitea.io/gitea/services/gitdiff"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/gitdiff"
)
// GetSingleCommit get a commit via sha
@ -189,7 +190,10 @@ func GetAllCommits(ctx *context.APIContext) {
userCache := make(map[string]*models.User)
apiCommits := make([]*api.Commit, commits.Len())
// =============================================================
// apiCommitsList := []api.Commit{}
// =================================================================
i := 0
for commitPointer := commits.Front(); commitPointer != nil; commitPointer = commitPointer.Next() {
commit := commitPointer.Value.(*git.Commit)
@ -200,6 +204,7 @@ func GetAllCommits(ctx *context.APIContext) {
ctx.ServerError("toCommit", err)
return
}
// apiCommitsList = append(apiCommitsList,*apiCommits[i])
i++
}
@ -214,9 +219,171 @@ func GetAllCommits(ctx *context.APIContext) {
ctx.SetLinkHeader(int(commitsCountTotal), listOptions.PageSize)
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", commitsCountTotal))
ctx.JSON(http.StatusOK, &apiCommits)
ctx.JSON(http.StatusOK, apiCommits)
}
// GetAllCommits get all commits via
func GetAllCommitsSliceByTime(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/commits_slice repository repoGetAllCommits
// ---
// summary: Get a list of all commits 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: 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/CommitList"
// "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.ServerError("OpenRepository", err)
return
}
defer gitRepo.Close()
listOptions := utils.GetListOptions(ctx)
if listOptions.Page <= 0 {
listOptions.Page = 1
}
if listOptions.PageSize > git.CommitsRangeSize {
listOptions.PageSize = git.CommitsRangeSize
}
sha := ctx.Query("sha")
var baseCommit *git.Commit
if len(sha) == 0 {
// no sha supplied - use default branch
head, err := gitRepo.GetHEADBranch()
if err != nil {
ctx.ServerError("GetHEADBranch", err)
return
}
baseCommit, err = gitRepo.GetBranchCommit(head.Name)
if err != nil {
ctx.ServerError("GetCommit", err)
return
}
} else {
// get commit specified by sha
baseCommit, err = gitRepo.GetCommit(sha)
if err != nil {
ctx.ServerError("GetCommit", err)
return
}
}
// Total commit count
commitsCountTotal, err := baseCommit.CommitsCount()
if err != nil {
ctx.ServerError("GetCommitsCount", err)
return
}
pageCount := int(math.Ceil(float64(commitsCountTotal) / float64(listOptions.PageSize)))
// Query commits
commits, err := baseCommit.CommitsByRange(listOptions.Page, listOptions.PageSize)
if err != nil {
ctx.ServerError("CommitsByRange", err)
return
}
userCache := make(map[string]*models.User)
apiCommits := make([]*api.Commit, commits.Len())
apiCommitsList := []api.Commit{}
i := 0
for commitPointer := commits.Front(); commitPointer != nil; commitPointer = commitPointer.Next() {
commit := commitPointer.Value.(*git.Commit)
// Create json struct
apiCommits[i], err = toCommit(ctx, ctx.Repo.Repository, commit, userCache)
if err != nil {
ctx.ServerError("toCommit", err)
return
}
apiCommitsList = append(apiCommitsList, *apiCommits[i])
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, CommitSplitSlice(apiCommitsList))
}
func CommitSplitSlice(CommitsList []api.Commit) []api.CommitsSlice {
// sort by time
sort.Sort(api.SortCommit(CommitsList))
Commits := make([]api.CommitsSlice,0)
i := 0
var j int
for {
if i >= len(CommitsList) {
break
}
// Detect equal CommitData,
for j = i + 1; j < len(CommitsList) && CommitsList[i].CommitDate == CommitsList[j].CommitDate; j++ {
}
// if equal, put commitdata in an array
commitDate := CommitsList[i].CommitDate
commitDatalist := CommitsList[i:j]
i = j // variable value
// get all the values,,,Commits
Commits = append(Commits, api.CommitsSlice{
CommitDate: commitDate,
Commits: commitDatalist,
})
}
return Commits
}
func toCommit(ctx *context.APIContext, repo *models.Repository, commit *git.Commit, userCache map[string]*models.User) (*api.Commit, error) {
var apiAuthor, apiCommitter *api.User
@ -279,6 +446,7 @@ func toCommit(ctx *context.APIContext, repo *models.Repository, commit *git.Comm
}
return &api.Commit{
CommitDate: commit.Committer.When.Format("2006-01-02"), // new time format, year-moon-day
CommitMeta: &api.CommitMeta{
URL: repo.APIURL() + "/git/commits/" + commit.ID.String(),
SHA: commit.ID.String(),
@ -315,8 +483,9 @@ func toCommit(ctx *context.APIContext, repo *models.Repository, commit *git.Comm
// add by qiubing
// 获取 Graph
func GetGraph(ctx *context.APIContext) {
if ctx.Repo.Repository.IsEmpty { // 项目是否为空
ctx.JSON(409, api.APIError{
ctx.JSON(http.StatusConflict, api.APIError{
Message: "Git Repository is empty.",
URL: setting.API.SwaggerURL,
})
@ -334,7 +503,7 @@ func GetGraph(ctx *context.APIContext) {
return
}
ctx.JSON(200, &graph)
ctx.JSON(http.StatusOK, &graph)
}
// 获取 commit diff
@ -350,7 +519,7 @@ func Diff(ctx *context.APIContext) {
ctx.NotFound("GetDiffCommit", err)
return
}
ctx.JSON(200, &diff)
ctx.JSON(http.StatusOK, &diff)
}
// 获取文件 blame 信息
@ -415,7 +584,7 @@ func GetCommitsCount(ctx *context.APIContext) {
ctx.ServerError("GetCommitsCount", err)
return
}
ctx.JSON(200, &ctx.Repo)
ctx.JSON(http.StatusOK, &ctx.Repo)
}
// end by qiubing

View File

@ -2443,6 +2443,39 @@
}
}
},
"/repos/{owner}/{repo}/branches/branches_slice": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "List a repository's branches, Group sort.",
"operationId": "repoListBranches",
"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
}
],
"responses": {
"200": {
"$ref": "#/responses/BranchList"
}
}
}
},
"/repos/{owner}/{repo}/branches/{branch}": {
"get": {
"produces": [
@ -2810,6 +2843,63 @@
}
}
},
"/repos/{owner}/{repo}/commits_slice": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Get a list of all commits from a repository",
"operationId": "repoGetAllCommits",
"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": "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/CommitList"
},
"404": {
"$ref": "#/responses/notFound"
},
"409": {
"$ref": "#/responses/EmptyRepository"
}
}
}
},
"/repos/{owner}/{repo}/contents": {
"get": {
"produces": [
@ -11303,9 +11393,26 @@
"description": "Branch represents a repository branch",
"type": "object",
"properties": {
"branch_kind": {
"type": "integer",
"format": "int64",
"x-go-name": "BranchKind"
},
"commit": {
"$ref": "#/definitions/PayloadCommit"
},
"commit_id": {
"type": "string",
"x-go-name": "CommitID"
},
"commit_time": {
"type": "string",
"x-go-name": "CommitTime"
},
"default_branch": {
"type": "string",
"x-go-name": "DefaultBranch"
},
"effective_branch_protection_name": {
"type": "string",
"x-go-name": "EffectiveBranchProtectionName"
@ -11530,7 +11637,6 @@
},
"Commit": {
"type": "object",
"title": "Commit contains information generated from a Git commit.",
"properties": {
"author": {
"$ref": "#/definitions/User"
@ -11538,6 +11644,10 @@
"commit": {
"$ref": "#/definitions/RepoCommit"
},
"commit_date": {
"type": "string",
"x-go-name": "CommitDate"
},
"committer": {
"$ref": "#/definitions/User"
},
@ -13976,14 +14086,17 @@
"type": "object",
"required": [
"clone_addr",
"uid",
"repo_name"
"uid"
],
"properties": {
"auth_password": {
"type": "string",
"x-go-name": "AuthPassword"
},
"auth_token": {
"type": "string",
"x-go-name": "AuthToken"
},
"auth_username": {
"type": "string",
"x-go-name": "AuthUsername"
@ -14012,6 +14125,10 @@
"type": "boolean",
"x-go-name": "Mirror"
},
"mirror_interval": {
"type": "string",
"x-go-name": "MirrorInterval"
},
"private": {
"type": "boolean",
"x-go-name": "Private"
@ -14028,6 +14145,15 @@
"type": "string",
"x-go-name": "RepoName"
},
"repo_owner": {
"type": "string",
"x-go-name": "RepoOwner"
},
"service": {
"description": "add configure",
"type": "string",
"x-go-name": "Service"
},
"uid": {
"type": "integer",
"format": "int64",
@ -16395,4 +16521,4 @@
"TOTPHeader": []
}
]
}
}