From 9634f568b5c1ba22291563c0f044d8411058a31d Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Mon, 15 Nov 2021 18:09:23 +0100 Subject: [PATCH 01/12] Add API to get file comment history --- integrations/api_repo_git_commits_test.go | 17 +++++ routers/api/v1/api.go | 1 + routers/api/v1/repo/file.go | 85 +++++++++++++++++++++++ templates/swagger/v1_json.tmpl | 55 +++++++++++++++ 4 files changed, 158 insertions(+) diff --git a/integrations/api_repo_git_commits_test.go b/integrations/api_repo_git_commits_test.go index 314416d2646e..242b28e6cf11 100644 --- a/integrations/api_repo_git_commits_test.go +++ b/integrations/api_repo_git_commits_test.go @@ -132,3 +132,20 @@ func TestDownloadCommitDiffOrPatch(t *testing.T) { resp.Body.String()) } + +func TestGetFileHistory(t *testing.T) { + user := db.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) + // Login as User2. + session := loginUser(t, user.Name) + token := getTokenForLoggedInUser(t, session) + + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/git/history/readme.md?token="+token+"&sha=good-sign", user.Name) + resp := session.MakeRequest(t, req, http.StatusOK) + + var apiData []api.Commit + DecodeJSON(t, resp, &apiData) + + assert.Len(t, apiData, 3) + assert.Equal(t, "69554a64c1e6030f051e5c3f94bfbd773cd6a324", apiData[0].CommitMeta.SHA) + compareCommitFiles(t, []string{"readme.md"}, apiData[0].Files) +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index f312df23db1a..6b0cd3804114 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -965,6 +965,7 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route { m.Get("/blobs/{sha}", context.RepoRefForAPI, repo.GetBlob) m.Get("/tags/{sha}", context.RepoRefForAPI, repo.GetAnnotatedTag) m.Get("/notes/{sha}", repo.GetNote) + m.Get("/history/*", context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetFileHistory) }, reqRepoReader(unit.TypeCode)) m.Group("/contents", func() { m.Get("", repo.GetContentsList) diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 009b8a26d60b..d439af198c6f 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -14,8 +14,10 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/repofiles" + "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/common" @@ -597,3 +599,86 @@ func GetContentsList(ctx *context.APIContext) { // same as GetContents(), this function is here because swagger fails if path is empty in GetContents() interface GetContents(ctx) } + +// GetFileHistory get a file's commit history +func GetFileHistory(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/git/history/{filepath} repository repoGetFileHistory + // --- + // summary: Get a file's commit history + // 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: ref + // in: query + // description: "The name of the commit/branch/tag. Default the repository’s default branch (usually master)" + // type: string + // required: false + // - name: page + // in: query + // description: page number of results to return (1-based) + // type: integer + // responses: + // "200": + // "$ref": "#/responses/CommitList" + // "404": + // "$ref": "#/responses/notFound" + + if ctx.Repo.Repository.IsEmpty { + ctx.NotFound() + return + } + + ref := ctx.FormTrim("ref") + if len(ref) < 1 { + ref = ctx.Repo.Repository.DefaultBranch + } + + page := ctx.FormInt("page") + if page <= 1 { + page = 1 + } + + commitsCount, err := ctx.Repo.GitRepo.FileCommitsCount(ref, ctx.Repo.TreePath) + if err != nil { + ctx.Error(http.StatusInternalServerError, "FileCommitsCount", err) + return + } else if commitsCount == 0 { + ctx.NotFound("FileCommitsCount", nil) + return + } + + commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(ref, ctx.Repo.TreePath, page) + if err != nil { + ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) + return + } + apiCommits := make([]*api.Commit, len(commits)) + for i, commit := range commits { + // Create json struct + apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, commit, make(map[string]*models.User)) + if err != nil { + ctx.Error(http.StatusInternalServerError, "toCommit", err) + return + } + } + + ctx.SetLinkHeader(int(commitsCount), setting.Git.CommitsRangeSize) + ctx.SetTotalCountHeader(commitsCount) + + ctx.JSON(http.StatusOK, &apiCommits) +} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 6bbc0934811b..ee770e3f9585 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3652,6 +3652,61 @@ } } }, + "/repos/{owner}/{repo}/git/history/{filepath}": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "repository" + ], + "summary": "Get a file's commit history", + "operationId": "repoGetFileHistory", + "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": "The name of the commit/branch/tag. Default the repository’s default branch (usually master)", + "name": "ref", + "in": "query" + }, + { + "type": "integer", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/CommitList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, "/repos/{owner}/{repo}/git/notes/{sha}": { "get": { "produces": [ From dc1c3a55e25609fc276c23fe94c9048b918e3425 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Mon, 15 Nov 2021 19:19:06 +0100 Subject: [PATCH 02/12] Update swagger description --- routers/api/v1/repo/file.go | 6 +++--- templates/swagger/v1_json.tmpl | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index d439af198c6f..9cafebe100e6 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -604,7 +604,7 @@ func GetContentsList(ctx *context.APIContext) { func GetFileHistory(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/git/history/{filepath} repository repoGetFileHistory // --- - // summary: Get a file's commit history + // summary: Get a file's or directory's commit history // produces: // - application/json // parameters: @@ -620,12 +620,12 @@ func GetFileHistory(ctx *context.APIContext) { // required: true // - name: filepath // in: path - // description: filepath of the file to get + // description: filepath of the file/directory // type: string // required: true // - name: ref // in: query - // description: "The name of the commit/branch/tag. Default the repository’s default branch (usually master)" + // description: "The name of the branch. Default the repository’s default branch (usually master)" // type: string // required: false // - name: page diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index ee770e3f9585..5adeff3b3882 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3660,7 +3660,7 @@ "tags": [ "repository" ], - "summary": "Get a file's commit history", + "summary": "Get a file's or directory's commit history", "operationId": "repoGetFileHistory", "parameters": [ { @@ -3679,14 +3679,14 @@ }, { "type": "string", - "description": "filepath of the file to get", + "description": "filepath of the file/directory", "name": "filepath", "in": "path", "required": true }, { "type": "string", - "description": "The name of the commit/branch/tag. Default the repository’s default branch (usually master)", + "description": "The name of the branch. Default the repository’s default branch (usually master)", "name": "ref", "in": "query" }, From f7b15df2dfa174e975a4fb130ecedfd812715157 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Tue, 16 Nov 2021 07:46:00 +0100 Subject: [PATCH 03/12] Update swagger --- routers/api/v1/repo/file.go | 2 +- templates/swagger/v1_json.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 9cafebe100e6..cc2c8e87935d 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -604,7 +604,7 @@ func GetContentsList(ctx *context.APIContext) { func GetFileHistory(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/git/history/{filepath} repository repoGetFileHistory // --- - // summary: Get a file's or directory's commit history + // summary: Get the commit history of a file or directory // produces: // - application/json // parameters: diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 5adeff3b3882..5a334f97bf1d 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3660,7 +3660,7 @@ "tags": [ "repository" ], - "summary": "Get a file's or directory's commit history", + "summary": "Get the commit history of a file or directory", "operationId": "repoGetFileHistory", "parameters": [ { From be658d7c180a4e16257340a9d616904cd303f1ad Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Tue, 16 Nov 2021 17:57:59 +0100 Subject: [PATCH 04/12] Use user cache --- routers/api/v1/repo/file.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index cc2c8e87935d..9f521f869e35 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -667,10 +667,12 @@ func GetFileHistory(ctx *context.APIContext) { ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) return } + + userCache := make(map[string]*models.User) apiCommits := make([]*api.Commit, len(commits)) for i, commit := range commits { // Create json struct - apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, commit, make(map[string]*models.User)) + apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, commit, userCache) if err != nil { ctx.Error(http.StatusInternalServerError, "toCommit", err) return From b19d8f0e1c52fef03342a637b170ec901dde575a Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Tue, 16 Nov 2021 19:02:18 +0100 Subject: [PATCH 05/12] Fix test --- integrations/api_repo_git_commits_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integrations/api_repo_git_commits_test.go b/integrations/api_repo_git_commits_test.go index 6e448c318504..099ff7820dc3 100644 --- a/integrations/api_repo_git_commits_test.go +++ b/integrations/api_repo_git_commits_test.go @@ -134,7 +134,8 @@ func TestDownloadCommitDiffOrPatch(t *testing.T) { } func TestGetFileHistory(t *testing.T) { - user := db.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) + defer prepareTestEnv(t)() + user := unittest.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) // Login as User2. session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) From c690801cea1c52e06e73b37a6c89ca9a9234c2f8 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Mon, 22 Nov 2021 15:10:16 +0100 Subject: [PATCH 06/12] Update desc --- routers/api/v1/repo/file.go | 2 +- templates/swagger/v1_json.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 9f521f869e35..5a274f7c8267 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -625,7 +625,7 @@ func GetFileHistory(ctx *context.APIContext) { // required: true // - name: ref // in: query - // description: "The name of the branch. Default the repository’s default branch (usually master)" + // description: "The name of the ref (branch/tag). Default the repository’s default branch" // type: string // required: false // - name: page diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 5a334f97bf1d..b0f06372502f 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -3686,7 +3686,7 @@ }, { "type": "string", - "description": "The name of the branch. Default the repository’s default branch (usually master)", + "description": "The name of the ref (branch/tag). Default the repository’s default branch", "name": "ref", "in": "query" }, From f91aba5bdbe3225298ed3f72071f609bece3520a Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Mon, 13 Dec 2021 15:19:28 +0100 Subject: [PATCH 07/12] Move func to commits.go --- routers/api/v1/repo/commits.go | 85 ++++++++++++++++++++++++++++++++ routers/api/v1/repo/file.go | 88 ---------------------------------- 2 files changed, 85 insertions(+), 88 deletions(-) diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 117fef08da38..6d37c9fc0119 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -264,3 +264,88 @@ func DownloadCommitDiffOrPatch(ctx *context.APIContext) { return } } + +// GetFileHistory get a file's commit history +func GetFileHistory(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/git/history/{filepath} repository repoGetFileHistory + // --- + // summary: Get the commit history of a file or directory + // 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/directory + // type: string + // required: true + // - name: ref + // in: query + // description: "The name of the ref (branch/tag). Default the repository’s default branch" + // type: string + // required: false + // - name: page + // in: query + // description: page number of results to return (1-based) + // type: integer + // responses: + // "200": + // "$ref": "#/responses/CommitList" + // "404": + // "$ref": "#/responses/notFound" + + if ctx.Repo.Repository.IsEmpty { + ctx.NotFound() + return + } + + ref := ctx.FormTrim("ref") + if len(ref) < 1 { + ref = ctx.Repo.Repository.DefaultBranch + } + + page := ctx.FormInt("page") + if page <= 1 { + page = 1 + } + + commitsCount, err := ctx.Repo.GitRepo.FileCommitsCount(ref, ctx.Repo.TreePath) + if err != nil { + ctx.Error(http.StatusInternalServerError, "FileCommitsCount", err) + return + } else if commitsCount == 0 { + ctx.NotFound("FileCommitsCount", nil) + return + } + + commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(ref, ctx.Repo.TreePath, page) + if err != nil { + ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) + return + } + + userCache := make(map[string]*user_model.User) + apiCommits := make([]*api.Commit, len(commits)) + for i, commit := range commits { + // Create json struct + apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, commit, userCache) + if err != nil { + ctx.Error(http.StatusInternalServerError, "toCommit", err) + return + } + } + + ctx.SetLinkHeader(int(commitsCount), setting.Git.CommitsRangeSize) + ctx.SetTotalCountHeader(commitsCount) + + ctx.JSON(http.StatusOK, &apiCommits) +} diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 7a469e29b523..98decfcb6f28 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -14,11 +14,8 @@ import ( "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" - user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/common" @@ -601,88 +598,3 @@ func GetContentsList(ctx *context.APIContext) { // same as GetContents(), this function is here because swagger fails if path is empty in GetContents() interface GetContents(ctx) } - -// GetFileHistory get a file's commit history -func GetFileHistory(ctx *context.APIContext) { - // swagger:operation GET /repos/{owner}/{repo}/git/history/{filepath} repository repoGetFileHistory - // --- - // summary: Get the commit history of a file or directory - // 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/directory - // type: string - // required: true - // - name: ref - // in: query - // description: "The name of the ref (branch/tag). Default the repository’s default branch" - // type: string - // required: false - // - name: page - // in: query - // description: page number of results to return (1-based) - // type: integer - // responses: - // "200": - // "$ref": "#/responses/CommitList" - // "404": - // "$ref": "#/responses/notFound" - - if ctx.Repo.Repository.IsEmpty { - ctx.NotFound() - return - } - - ref := ctx.FormTrim("ref") - if len(ref) < 1 { - ref = ctx.Repo.Repository.DefaultBranch - } - - page := ctx.FormInt("page") - if page <= 1 { - page = 1 - } - - commitsCount, err := ctx.Repo.GitRepo.FileCommitsCount(ref, ctx.Repo.TreePath) - if err != nil { - ctx.Error(http.StatusInternalServerError, "FileCommitsCount", err) - return - } else if commitsCount == 0 { - ctx.NotFound("FileCommitsCount", nil) - return - } - - commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(ref, ctx.Repo.TreePath, page) - if err != nil { - ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) - return - } - - userCache := make(map[string]*user_model.User) - apiCommits := make([]*api.Commit, len(commits)) - for i, commit := range commits { - // Create json struct - apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, commit, userCache) - if err != nil { - ctx.Error(http.StatusInternalServerError, "toCommit", err) - return - } - } - - ctx.SetLinkHeader(int(commitsCount), setting.Git.CommitsRangeSize) - ctx.SetTotalCountHeader(commitsCount) - - ctx.JSON(http.StatusOK, &apiCommits) -} From 4ebd8c0f940d8c26632f03440bf215df674c1b27 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Mon, 13 Dec 2021 16:07:24 +0100 Subject: [PATCH 08/12] Use GitHub-compatible endpoint --- integrations/api_repo_git_commits_test.go | 2 +- routers/api/v1/api.go | 1 - routers/api/v1/repo/commits.go | 166 ++++++++-------------- 3 files changed, 57 insertions(+), 112 deletions(-) diff --git a/integrations/api_repo_git_commits_test.go b/integrations/api_repo_git_commits_test.go index c469f6bb0c91..5ef6ec17f2ae 100644 --- a/integrations/api_repo_git_commits_test.go +++ b/integrations/api_repo_git_commits_test.go @@ -140,7 +140,7 @@ func TestGetFileHistory(t *testing.T) { session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/git/history/readme.md?token="+token+"&sha=good-sign", user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?path=readme.md&token="+token+"&sha=good-sign", user.Name) resp := session.MakeRequest(t, req, http.StatusOK) var apiData []api.Commit diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 53360f6cc7f4..af5ab96d0531 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -971,7 +971,6 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route { m.Get("/blobs/{sha}", context.RepoRefForAPI, repo.GetBlob) m.Get("/tags/{sha}", context.RepoRefForAPI, repo.GetAnnotatedTag) m.Get("/notes/{sha}", repo.GetNote) - m.Get("/history/*", context.RepoRefForAPI, reqRepoReader(unit.TypeCode), repo.GetFileHistory) }, reqRepoReader(unit.TypeCode)) m.Group("/contents", func() { m.Get("", repo.GetContentsList) diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 6d37c9fc0119..6d5cc944e05d 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -108,13 +108,17 @@ func GetAllCommits(ctx *context.APIContext) { // in: query // description: SHA or branch to start listing commits from (usually 'master') // type: string + // - name: path + // in: query + // description: filepath of a file/dir + // 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 + // description: page size of results (ignored if used with 'path') // type: integer // responses: // "200": @@ -149,46 +153,73 @@ func GetAllCommits(ctx *context.APIContext) { } sha := ctx.FormString("sha") + path := ctx.FormString("path") + + var ( + commitsCountTotal int64 + commits []*git.Commit + ) + + if len(path) == 0 { + var baseCommit *git.Commit + if len(sha) == 0 { + // no sha supplied - use default branch + 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 + } + } else { + // get commit specified by sha + baseCommit, err = gitRepo.GetCommit(sha) + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetCommit", err) + return + } + } - var baseCommit *git.Commit - if len(sha) == 0 { - // no sha supplied - use default branch - head, err := gitRepo.GetHEADBranch() + // Total commit count + commitsCountTotal, err = baseCommit.CommitsCount() if err != nil { - ctx.Error(http.StatusInternalServerError, "GetHEADBranch", err) + ctx.Error(http.StatusInternalServerError, "GetCommitsCount", err) return } - baseCommit, err = gitRepo.GetBranchCommit(head.Name) + // Query commits + commits, err = baseCommit.CommitsByRange(listOptions.Page, listOptions.PageSize) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommit", err) + ctx.Error(http.StatusInternalServerError, "CommitsByRange", err) return } } else { - // get commit specified by sha - baseCommit, err = gitRepo.GetCommit(sha) + if len(sha) == 0 { + sha = ctx.Repo.Repository.DefaultBranch + } + + commitsCountTotal, err = gitRepo.FileCommitsCount(sha, path) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommit", err) + ctx.Error(http.StatusInternalServerError, "FileCommitsCount", err) + return + } else if commitsCountTotal == 0 { + ctx.NotFound("FileCommitsCount", nil) + return + } + + commits, err = gitRepo.CommitsByFileAndRange(sha, path, listOptions.PageSize) + if err != nil { + ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) return } - } - - // Total commit count - commitsCountTotal, err := baseCommit.CommitsCount() - if err != nil { - ctx.Error(http.StatusInternalServerError, "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.Error(http.StatusInternalServerError, "CommitsByRange", err) - return - } - userCache := make(map[string]*user_model.User) apiCommits := make([]*api.Commit, len(commits)) @@ -264,88 +295,3 @@ func DownloadCommitDiffOrPatch(ctx *context.APIContext) { return } } - -// GetFileHistory get a file's commit history -func GetFileHistory(ctx *context.APIContext) { - // swagger:operation GET /repos/{owner}/{repo}/git/history/{filepath} repository repoGetFileHistory - // --- - // summary: Get the commit history of a file or directory - // 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/directory - // type: string - // required: true - // - name: ref - // in: query - // description: "The name of the ref (branch/tag). Default the repository’s default branch" - // type: string - // required: false - // - name: page - // in: query - // description: page number of results to return (1-based) - // type: integer - // responses: - // "200": - // "$ref": "#/responses/CommitList" - // "404": - // "$ref": "#/responses/notFound" - - if ctx.Repo.Repository.IsEmpty { - ctx.NotFound() - return - } - - ref := ctx.FormTrim("ref") - if len(ref) < 1 { - ref = ctx.Repo.Repository.DefaultBranch - } - - page := ctx.FormInt("page") - if page <= 1 { - page = 1 - } - - commitsCount, err := ctx.Repo.GitRepo.FileCommitsCount(ref, ctx.Repo.TreePath) - if err != nil { - ctx.Error(http.StatusInternalServerError, "FileCommitsCount", err) - return - } else if commitsCount == 0 { - ctx.NotFound("FileCommitsCount", nil) - return - } - - commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(ref, ctx.Repo.TreePath, page) - if err != nil { - ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) - return - } - - userCache := make(map[string]*user_model.User) - apiCommits := make([]*api.Commit, len(commits)) - for i, commit := range commits { - // Create json struct - apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, commit, userCache) - if err != nil { - ctx.Error(http.StatusInternalServerError, "toCommit", err) - return - } - } - - ctx.SetLinkHeader(int(commitsCount), setting.Git.CommitsRangeSize) - ctx.SetTotalCountHeader(commitsCount) - - ctx.JSON(http.StatusOK, &apiCommits) -} From 92e3de5ef284def7075cd0cd80337670545adc10 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Mon, 13 Dec 2021 16:07:59 +0100 Subject: [PATCH 09/12] Update swagger --- templates/swagger/v1_json.tmpl | 63 ++++------------------------------ 1 file changed, 7 insertions(+), 56 deletions(-) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index b0f06372502f..7aed8c4bb5ba 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -2950,6 +2950,12 @@ "name": "sha", "in": "query" }, + { + "type": "string", + "description": "filepath of a file/dir", + "name": "path", + "in": "query" + }, { "type": "integer", "description": "page number of results to return (1-based)", @@ -2958,7 +2964,7 @@ }, { "type": "integer", - "description": "page size of results", + "description": "page size of results (ignored if used with 'path')", "name": "limit", "in": "query" } @@ -3652,61 +3658,6 @@ } } }, - "/repos/{owner}/{repo}/git/history/{filepath}": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "repository" - ], - "summary": "Get the commit history of a file or directory", - "operationId": "repoGetFileHistory", - "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/directory", - "name": "filepath", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "The name of the ref (branch/tag). Default the repository’s default branch", - "name": "ref", - "in": "query" - }, - { - "type": "integer", - "description": "page number of results to return (1-based)", - "name": "page", - "in": "query" - } - ], - "responses": { - "200": { - "$ref": "#/responses/CommitList" - }, - "404": { - "$ref": "#/responses/notFound" - } - } - } - }, "/repos/{owner}/{repo}/git/notes/{sha}": { "get": { "produces": [ From 887addba23e6fbd0892cf7d9cd9fe63a28494b22 Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Mon, 13 Dec 2021 16:08:53 +0100 Subject: [PATCH 10/12] fmt --- modules/indexer/code/indexer_test.go | 3 ++- modules/indexer/issues/indexer_test.go | 3 ++- modules/indexer/stats/indexer_test.go | 3 ++- routers/api/v1/repo/commits.go | 4 ++-- services/asymkey/ssh_key_test.go | 1 + services/mailer/mailer_test.go | 1 + services/webhook/main_test.go | 3 ++- 7 files changed, 12 insertions(+), 6 deletions(-) diff --git a/modules/indexer/code/indexer_test.go b/modules/indexer/code/indexer_test.go index 98494afceb24..42f21ed0df2d 100644 --- a/modules/indexer/code/indexer_test.go +++ b/modules/indexer/code/indexer_test.go @@ -8,9 +8,10 @@ import ( "path/filepath" "testing" - _ "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/unittest" + _ "code.gitea.io/gitea/models" + "github.com/stretchr/testify/assert" ) diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go index 0855165556da..866e3cc7c920 100644 --- a/modules/indexer/issues/indexer_test.go +++ b/modules/indexer/issues/indexer_test.go @@ -11,11 +11,12 @@ import ( "testing" "time" - _ "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" + _ "code.gitea.io/gitea/models" + "github.com/stretchr/testify/assert" "gopkg.in/ini.v1" ) diff --git a/modules/indexer/stats/indexer_test.go b/modules/indexer/stats/indexer_test.go index b32100b45829..50c6cc38e9bb 100644 --- a/modules/indexer/stats/indexer_test.go +++ b/modules/indexer/stats/indexer_test.go @@ -9,11 +9,12 @@ import ( "testing" "time" - _ "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" + _ "code.gitea.io/gitea/models" + "github.com/stretchr/testify/assert" "gopkg.in/ini.v1" ) diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 6d5cc944e05d..9ccc68b1c9be 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -157,7 +157,7 @@ func GetAllCommits(ctx *context.APIContext) { var ( commitsCountTotal int64 - commits []*git.Commit + commits []*git.Commit ) if len(path) == 0 { @@ -210,7 +210,7 @@ func GetAllCommits(ctx *context.APIContext) { ctx.NotFound("FileCommitsCount", nil) return } - + commits, err = gitRepo.CommitsByFileAndRange(sha, path, listOptions.PageSize) if err != nil { ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) diff --git a/services/asymkey/ssh_key_test.go b/services/asymkey/ssh_key_test.go index 0ce235f7f65c..9de6a4c11bbd 100644 --- a/services/asymkey/ssh_key_test.go +++ b/services/asymkey/ssh_key_test.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models/login" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" + "github.com/stretchr/testify/assert" ) diff --git a/services/mailer/mailer_test.go b/services/mailer/mailer_test.go index 1739a68a6441..56f2eb52b0bc 100644 --- a/services/mailer/mailer_test.go +++ b/services/mailer/mailer_test.go @@ -9,6 +9,7 @@ import ( "time" "code.gitea.io/gitea/modules/setting" + "github.com/stretchr/testify/assert" ) diff --git a/services/webhook/main_test.go b/services/webhook/main_test.go index e64acf3b6112..a87b74e89d74 100644 --- a/services/webhook/main_test.go +++ b/services/webhook/main_test.go @@ -8,8 +8,9 @@ import ( "path/filepath" "testing" - _ "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/unittest" + + _ "code.gitea.io/gitea/models" ) func TestMain(m *testing.M) { From 01c8883c7f2d42ea9894ba4179c0b5be5d06e70d Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Tue, 21 Dec 2021 09:47:10 +0100 Subject: [PATCH 11/12] Fix empty list --- routers/api/v1/repo/commits.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index c8e31cd0e7a6..a2b42986020b 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -211,7 +211,7 @@ func GetAllCommits(ctx *context.APIContext) { return } - commits, err = gitRepo.CommitsByFileAndRange(sha, path, listOptions.PageSize) + commits, err = gitRepo.CommitsByFileAndRange(sha, path, listOptions.Page) if err != nil { ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) return From 07f853ed649fc0f1eecbd46997589265d4ae0d5b Mon Sep 17 00:00:00 2001 From: qwerty287 Date: Tue, 21 Dec 2021 09:57:47 +0100 Subject: [PATCH 12/12] Fix test --- integrations/api_repo_git_commits_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integrations/api_repo_git_commits_test.go b/integrations/api_repo_git_commits_test.go index 5ef6ec17f2ae..2099d568f769 100644 --- a/integrations/api_repo_git_commits_test.go +++ b/integrations/api_repo_git_commits_test.go @@ -146,7 +146,7 @@ func TestGetFileHistory(t *testing.T) { var apiData []api.Commit DecodeJSON(t, resp, &apiData) - assert.Len(t, apiData, 3) - assert.Equal(t, "69554a64c1e6030f051e5c3f94bfbd773cd6a324", apiData[0].CommitMeta.SHA) + assert.Len(t, apiData, 1) + assert.Equal(t, "f27c2b2b03dcab38beaf89b0ab4ff61f6de63441", apiData[0].CommitMeta.SHA) compareCommitFiles(t, []string{"readme.md"}, apiData[0].Files) }