aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorJordan Levin <31293855+jaylevin@users.noreply.github.com>2021-09-23 09:33:52 -0700
committerGitHub <noreply@github.com>2021-09-24 00:33:52 +0800
commitb9a3626cad505b1dccd66a0b023263ef59134430 (patch)
tree7add86378833ea4ed2a85279ea746c9d0306e7c1 /internal
parentb3eb33be0fa343522e1f3ea6397534b40e8dde37 (diff)
api: add `GET /api/v1/{owner}/{repo}/commits` endpoint (#6574)
This pull request targets issue #6573. It provides a new API endpoint: `/api/v1/repos/{org}/{repo}/commits?pageSize=<int>` with a default page size of 30 commits (the same as the UI). This implementation currently only focuses on the main/master branch of the repository, and does not provide the ability to return commit history for other branches. - Note: Since the logic for converting a git.Commit to api.Commit had to be used in `GetAllCommits` and `GetSingleCommit`, I decided to pull the code out into a helper function, ` gitCommitToAPICommit(commit, context)`.
Diffstat (limited to 'internal')
-rw-r--r--internal/route/api/v1/api.go1
-rw-r--r--internal/route/api/v1/repo/commits.go132
2 files changed, 88 insertions, 45 deletions
diff --git a/internal/route/api/v1/api.go b/internal/route/api/v1/api.go
index 13de45b2..542c386e 100644
--- a/internal/route/api/v1/api.go
+++ b/internal/route/api/v1/api.go
@@ -286,6 +286,7 @@ func RegisterRoutes(m *macaron.Macaron) {
})
m.Group("/commits", func() {
m.Get("/:sha", repo.GetSingleCommit)
+ m.Get("", repo.GetAllCommits)
m.Get("/*", repo.GetReferenceSHA)
})
diff --git a/internal/route/api/v1/repo/commits.go b/internal/route/api/v1/repo/commits.go
index ea6590d7..5b3280a1 100644
--- a/internal/route/api/v1/repo/commits.go
+++ b/internal/route/api/v1/repo/commits.go
@@ -18,6 +18,40 @@ import (
"gogs.io/gogs/internal/gitutil"
)
+// GetAllCommits returns a slice of commits starting from HEAD.
+func GetAllCommits(c *context.APIContext) {
+ // Get pagesize, set default if it is not specified.
+ pageSize := c.QueryInt("pageSize")
+ if pageSize == 0 {
+ pageSize = 30
+ }
+
+ gitRepo, err := git.Open(c.Repo.Repository.RepoPath())
+ if err != nil {
+ c.Error(err, "open repository")
+ return
+ }
+
+ // The response object returned as JSON
+ result := make([]*api.Commit, 0, pageSize)
+ commits, err := gitRepo.Log("HEAD", git.LogOptions{MaxCount: pageSize})
+ if err != nil {
+ c.Error(err, "git log")
+ }
+
+ for _, commit := range commits {
+ apiCommit, err := gitCommitToAPICommit(commit, c)
+ if err != nil {
+ c.Error(err, "convert git commit to api commit")
+ return
+ }
+ result = append(result, apiCommit)
+ }
+
+ c.JSONSuccess(result)
+}
+
+// GetSingleCommit will return a single Commit object based on the specified SHA.
func GetSingleCommit(c *context.APIContext) {
if strings.Contains(c.Req.Header.Get("Accept"), api.MediaApplicationSHA) {
c.SetParams("*", c.Params(":sha"))
@@ -36,23 +70,70 @@ func GetSingleCommit(c *context.APIContext) {
return
}
+ apiCommit, err := gitCommitToAPICommit(commit, c)
+ if err != nil {
+ c.Error(err, "convert git commit to api commit")
+ }
+ c.JSONSuccess(apiCommit)
+}
+
+func GetReferenceSHA(c *context.APIContext) {
+ gitRepo, err := git.Open(c.Repo.Repository.RepoPath())
+ if err != nil {
+ c.Error(err, "open repository")
+ return
+ }
+
+ ref := c.Params("*")
+ refType := 0 // 0-unknown, 1-branch, 2-tag
+ if strings.HasPrefix(ref, git.RefsHeads) {
+ ref = strings.TrimPrefix(ref, git.RefsHeads)
+ refType = 1
+ } else if strings.HasPrefix(ref, git.RefsTags) {
+ ref = strings.TrimPrefix(ref, git.RefsTags)
+ refType = 2
+ } else {
+ if gitRepo.HasBranch(ref) {
+ refType = 1
+ } else if gitRepo.HasTag(ref) {
+ refType = 2
+ } else {
+ c.NotFound()
+ return
+ }
+ }
+
+ var sha string
+ if refType == 1 {
+ sha, err = gitRepo.BranchCommitID(ref)
+ } else if refType == 2 {
+ sha, err = gitRepo.TagCommitID(ref)
+ }
+ if err != nil {
+ c.NotFoundOrError(gitutil.NewError(err), "get reference commit ID")
+ return
+ }
+ c.PlainText(http.StatusOK, sha)
+}
+
+// gitCommitToApiCommit is a helper function to convert git commit object to API commit.
+func gitCommitToAPICommit(commit *git.Commit, c *context.APIContext) (*api.Commit, error) {
// Retrieve author and committer information
var apiAuthor, apiCommitter *api.User
author, err := db.GetUserByEmail(commit.Author.Email)
if err != nil && !db.IsErrUserNotExist(err) {
- c.Error(err, "get user by author email")
- return
+ return nil, err
} else if err == nil {
apiAuthor = author.APIFormat()
}
+
// Save one query if the author is also the committer
if commit.Committer.Email == commit.Author.Email {
apiCommitter = apiAuthor
} else {
committer, err := db.GetUserByEmail(commit.Committer.Email)
if err != nil && !db.IsErrUserNotExist(err) {
- c.Error(err, "get user by committer email")
- return
+ return nil, err
} else if err == nil {
apiCommitter = committer.APIFormat()
}
@@ -68,7 +149,7 @@ func GetSingleCommit(c *context.APIContext) {
}
}
- c.JSONSuccess(&api.Commit{
+ return &api.Commit{
CommitMeta: &api.CommitMeta{
URL: conf.Server.ExternalURL + c.Link[1:],
SHA: commit.ID.String(),
@@ -95,44 +176,5 @@ func GetSingleCommit(c *context.APIContext) {
Author: apiAuthor,
Committer: apiCommitter,
Parents: apiParents,
- })
-}
-
-func GetReferenceSHA(c *context.APIContext) {
- gitRepo, err := git.Open(c.Repo.Repository.RepoPath())
- if err != nil {
- c.Error(err, "open repository")
- return
- }
-
- ref := c.Params("*")
- refType := 0 // 0-unknown, 1-branch, 2-tag
- if strings.HasPrefix(ref, git.RefsHeads) {
- ref = strings.TrimPrefix(ref, git.RefsHeads)
- refType = 1
- } else if strings.HasPrefix(ref, git.RefsTags) {
- ref = strings.TrimPrefix(ref, git.RefsTags)
- refType = 2
- } else {
- if gitRepo.HasBranch(ref) {
- refType = 1
- } else if gitRepo.HasTag(ref) {
- refType = 2
- } else {
- c.NotFound()
- return
- }
- }
-
- var sha string
- if refType == 1 {
- sha, err = gitRepo.BranchCommitID(ref)
- } else if refType == 2 {
- sha, err = gitRepo.TagCommitID(ref)
- }
- if err != nil {
- c.NotFoundOrError(gitutil.NewError(err), "get reference commit ID")
- return
- }
- c.PlainText(http.StatusOK, sha)
+ }, nil
}