diff options
author | Jordan Levin <31293855+jaylevin@users.noreply.github.com> | 2021-09-23 09:33:52 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-24 00:33:52 +0800 |
commit | b9a3626cad505b1dccd66a0b023263ef59134430 (patch) | |
tree | 7add86378833ea4ed2a85279ea746c9d0306e7c1 /internal | |
parent | b3eb33be0fa343522e1f3ea6397534b40e8dde37 (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.go | 1 | ||||
-rw-r--r-- | internal/route/api/v1/repo/commits.go | 132 |
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 } |