commits.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright 2018 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package repo
  5. import (
  6. "net/http"
  7. "strings"
  8. "time"
  9. "github.com/gogs/git-module"
  10. api "github.com/gogs/go-gogs-client"
  11. "gogs.io/gogs/internal/conf"
  12. "gogs.io/gogs/internal/context"
  13. "gogs.io/gogs/internal/db"
  14. "gogs.io/gogs/internal/db/errors"
  15. "gogs.io/gogs/internal/gitutil"
  16. )
  17. func GetSingleCommit(c *context.APIContext) {
  18. if strings.Contains(c.Req.Header.Get("Accept"), api.MediaApplicationSHA) {
  19. c.SetParams("*", c.Params(":sha"))
  20. GetReferenceSHA(c)
  21. return
  22. }
  23. gitRepo, err := git.Open(c.Repo.Repository.RepoPath())
  24. if err != nil {
  25. c.ServerError("open repository", err)
  26. return
  27. }
  28. commit, err := gitRepo.CatFileCommit(c.Params(":sha"))
  29. if err != nil {
  30. c.NotFoundOrServerError("get commit", gitutil.IsErrRevisionNotExist, err)
  31. return
  32. }
  33. // Retrieve author and committer information
  34. var apiAuthor, apiCommitter *api.User
  35. author, err := db.GetUserByEmail(commit.Author.Email)
  36. if err != nil && !errors.IsUserNotExist(err) {
  37. c.ServerError("Get user by author email", err)
  38. return
  39. } else if err == nil {
  40. apiAuthor = author.APIFormat()
  41. }
  42. // Save one query if the author is also the committer
  43. if commit.Committer.Email == commit.Author.Email {
  44. apiCommitter = apiAuthor
  45. } else {
  46. committer, err := db.GetUserByEmail(commit.Committer.Email)
  47. if err != nil && !errors.IsUserNotExist(err) {
  48. c.ServerError("Get user by committer email", err)
  49. return
  50. } else if err == nil {
  51. apiCommitter = committer.APIFormat()
  52. }
  53. }
  54. // Retrieve parent(s) of the commit
  55. apiParents := make([]*api.CommitMeta, commit.ParentsCount())
  56. for i := 0; i < commit.ParentsCount(); i++ {
  57. sha, _ := commit.ParentID(i)
  58. apiParents[i] = &api.CommitMeta{
  59. URL: c.BaseURL + "/repos/" + c.Repo.Repository.FullName() + "/commits/" + sha.String(),
  60. SHA: sha.String(),
  61. }
  62. }
  63. c.JSONSuccess(&api.Commit{
  64. CommitMeta: &api.CommitMeta{
  65. URL: conf.Server.ExternalURL + c.Link[1:],
  66. SHA: commit.ID.String(),
  67. },
  68. HTMLURL: c.Repo.Repository.HTMLURL() + "/commits/" + commit.ID.String(),
  69. RepoCommit: &api.RepoCommit{
  70. URL: conf.Server.ExternalURL + c.Link[1:],
  71. Author: &api.CommitUser{
  72. Name: commit.Author.Name,
  73. Email: commit.Author.Email,
  74. Date: commit.Author.When.Format(time.RFC3339),
  75. },
  76. Committer: &api.CommitUser{
  77. Name: commit.Committer.Name,
  78. Email: commit.Committer.Email,
  79. Date: commit.Committer.When.Format(time.RFC3339),
  80. },
  81. Message: commit.Summary(),
  82. Tree: &api.CommitMeta{
  83. URL: c.BaseURL + "/repos/" + c.Repo.Repository.FullName() + "/tree/" + commit.ID.String(),
  84. SHA: commit.ID.String(),
  85. },
  86. },
  87. Author: apiAuthor,
  88. Committer: apiCommitter,
  89. Parents: apiParents,
  90. })
  91. }
  92. func GetReferenceSHA(c *context.APIContext) {
  93. gitRepo, err := git.Open(c.Repo.Repository.RepoPath())
  94. if err != nil {
  95. c.ServerError("open repository", err)
  96. return
  97. }
  98. ref := c.Params("*")
  99. refType := 0 // 0-unknown, 1-branch, 2-tag
  100. if strings.HasPrefix(ref, git.RefsHeads) {
  101. ref = strings.TrimPrefix(ref, git.RefsHeads)
  102. refType = 1
  103. } else if strings.HasPrefix(ref, git.RefsTags) {
  104. ref = strings.TrimPrefix(ref, git.RefsTags)
  105. refType = 2
  106. } else {
  107. if gitRepo.HasBranch(ref) {
  108. refType = 1
  109. } else if gitRepo.HasTag(ref) {
  110. refType = 2
  111. } else {
  112. c.NotFound()
  113. return
  114. }
  115. }
  116. var sha string
  117. if refType == 1 {
  118. sha, err = gitRepo.BranchCommitID(ref)
  119. } else if refType == 2 {
  120. sha, err = gitRepo.TagCommitID(ref)
  121. }
  122. if err != nil {
  123. c.NotFoundOrServerError("get reference commit ID", gitutil.IsErrRevisionNotExist, err)
  124. return
  125. }
  126. c.PlainText(http.StatusOK, []byte(sha))
  127. }