1
0
Эх сурвалжийг харах

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)`.
Jordan Levin 3 жил өмнө
parent
commit
b9a3626cad

+ 1 - 0
internal/route/api/v1/api.go

@@ -286,6 +286,7 @@ func RegisterRoutes(m *macaron.Macaron) {
 				})
 				})
 				m.Group("/commits", func() {
 				m.Group("/commits", func() {
 					m.Get("/:sha", repo.GetSingleCommit)
 					m.Get("/:sha", repo.GetSingleCommit)
+					m.Get("", repo.GetAllCommits)
 					m.Get("/*", repo.GetReferenceSHA)
 					m.Get("/*", repo.GetReferenceSHA)
 				})
 				})
 
 

+ 87 - 45
internal/route/api/v1/repo/commits.go

@@ -18,6 +18,40 @@ import (
 	"gogs.io/gogs/internal/gitutil"
 	"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) {
 func GetSingleCommit(c *context.APIContext) {
 	if strings.Contains(c.Req.Header.Get("Accept"), api.MediaApplicationSHA) {
 	if strings.Contains(c.Req.Header.Get("Accept"), api.MediaApplicationSHA) {
 		c.SetParams("*", c.Params(":sha"))
 		c.SetParams("*", c.Params(":sha"))
@@ -36,23 +70,70 @@ func GetSingleCommit(c *context.APIContext) {
 		return
 		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
 	// Retrieve author and committer information
 	var apiAuthor, apiCommitter *api.User
 	var apiAuthor, apiCommitter *api.User
 	author, err := db.GetUserByEmail(commit.Author.Email)
 	author, err := db.GetUserByEmail(commit.Author.Email)
 	if err != nil && !db.IsErrUserNotExist(err) {
 	if err != nil && !db.IsErrUserNotExist(err) {
-		c.Error(err, "get user by author email")
-		return
+		return nil, err
 	} else if err == nil {
 	} else if err == nil {
 		apiAuthor = author.APIFormat()
 		apiAuthor = author.APIFormat()
 	}
 	}
+
 	// Save one query if the author is also the committer
 	// Save one query if the author is also the committer
 	if commit.Committer.Email == commit.Author.Email {
 	if commit.Committer.Email == commit.Author.Email {
 		apiCommitter = apiAuthor
 		apiCommitter = apiAuthor
 	} else {
 	} else {
 		committer, err := db.GetUserByEmail(commit.Committer.Email)
 		committer, err := db.GetUserByEmail(commit.Committer.Email)
 		if err != nil && !db.IsErrUserNotExist(err) {
 		if err != nil && !db.IsErrUserNotExist(err) {
-			c.Error(err, "get user by committer email")
-			return
+			return nil, err
 		} else if err == nil {
 		} else if err == nil {
 			apiCommitter = committer.APIFormat()
 			apiCommitter = committer.APIFormat()
 		}
 		}
@@ -68,7 +149,7 @@ func GetSingleCommit(c *context.APIContext) {
 		}
 		}
 	}
 	}
 
 
-	c.JSONSuccess(&api.Commit{
+	return &api.Commit{
 		CommitMeta: &api.CommitMeta{
 		CommitMeta: &api.CommitMeta{
 			URL: conf.Server.ExternalURL + c.Link[1:],
 			URL: conf.Server.ExternalURL + c.Link[1:],
 			SHA: commit.ID.String(),
 			SHA: commit.ID.String(),
@@ -95,44 +176,5 @@ func GetSingleCommit(c *context.APIContext) {
 		Author:    apiAuthor,
 		Author:    apiAuthor,
 		Committer: apiCommitter,
 		Committer: apiCommitter,
 		Parents:   apiParents,
 		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
 }
 }