You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

commit.go 7.8 kB

11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. // Copyright 2014 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. "container/list"
  7. "path"
  8. "code.gitea.io/git"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/base"
  11. "code.gitea.io/gitea/modules/context"
  12. "code.gitea.io/gitea/modules/setting"
  13. "github.com/Unknwon/paginater"
  14. )
  15. const (
  16. tplCommits base.TplName = "repo/commits"
  17. tplDiff base.TplName = "repo/diff/page"
  18. )
  19. // RefCommits render commits page
  20. func RefCommits(ctx *context.Context) {
  21. switch {
  22. case len(ctx.Repo.TreePath) == 0:
  23. Commits(ctx)
  24. case ctx.Repo.TreePath == "search":
  25. SearchCommits(ctx)
  26. default:
  27. FileHistory(ctx)
  28. }
  29. }
  30. func renderIssueLinks(oldCommits *list.List, repoLink string) *list.List {
  31. newCommits := list.New()
  32. for e := oldCommits.Front(); e != nil; e = e.Next() {
  33. c := e.Value.(*git.Commit)
  34. newCommits.PushBack(c)
  35. }
  36. return newCommits
  37. }
  38. // Commits render branch's commits
  39. func Commits(ctx *context.Context) {
  40. ctx.Data["PageIsCommits"] = true
  41. commitsCount, err := ctx.Repo.Commit.CommitsCount()
  42. if err != nil {
  43. ctx.Handle(500, "GetCommitsCount", err)
  44. return
  45. }
  46. page := ctx.QueryInt("page")
  47. if page <= 1 {
  48. page = 1
  49. }
  50. ctx.Data["Page"] = paginater.New(int(commitsCount), git.CommitsRangeSize, page, 5)
  51. // Both `git log branchName` and `git log commitId` work.
  52. commits, err := ctx.Repo.Commit.CommitsByRange(page)
  53. if err != nil {
  54. ctx.Handle(500, "CommitsByRange", err)
  55. return
  56. }
  57. commits = renderIssueLinks(commits, ctx.Repo.RepoLink)
  58. commits = models.ValidateCommitsWithEmails(commits)
  59. ctx.Data["Commits"] = commits
  60. ctx.Data["Username"] = ctx.Repo.Owner.Name
  61. ctx.Data["Reponame"] = ctx.Repo.Repository.Name
  62. ctx.Data["CommitCount"] = commitsCount
  63. ctx.Data["Branch"] = ctx.Repo.BranchName
  64. ctx.HTML(200, tplCommits)
  65. }
  66. // SearchCommits render commits filtered by keyword
  67. func SearchCommits(ctx *context.Context) {
  68. ctx.Data["PageIsCommits"] = true
  69. keyword := ctx.Query("q")
  70. if len(keyword) == 0 {
  71. ctx.Redirect(ctx.Repo.RepoLink + "/commits/" + ctx.Repo.BranchName)
  72. return
  73. }
  74. commits, err := ctx.Repo.Commit.SearchCommits(keyword)
  75. if err != nil {
  76. ctx.Handle(500, "SearchCommits", err)
  77. return
  78. }
  79. commits = renderIssueLinks(commits, ctx.Repo.RepoLink)
  80. commits = models.ValidateCommitsWithEmails(commits)
  81. ctx.Data["Commits"] = commits
  82. ctx.Data["Keyword"] = keyword
  83. ctx.Data["Username"] = ctx.Repo.Owner.Name
  84. ctx.Data["Reponame"] = ctx.Repo.Repository.Name
  85. ctx.Data["CommitCount"] = commits.Len()
  86. ctx.Data["Branch"] = ctx.Repo.BranchName
  87. ctx.HTML(200, tplCommits)
  88. }
  89. // FileHistory show a file's reversions
  90. func FileHistory(ctx *context.Context) {
  91. ctx.Data["IsRepoToolbarCommits"] = true
  92. fileName := ctx.Repo.TreePath
  93. if len(fileName) == 0 {
  94. Commits(ctx)
  95. return
  96. }
  97. branchName := ctx.Repo.BranchName
  98. commitsCount, err := ctx.Repo.GitRepo.FileCommitsCount(branchName, fileName)
  99. if err != nil {
  100. ctx.Handle(500, "FileCommitsCount", err)
  101. return
  102. } else if commitsCount == 0 {
  103. ctx.Handle(404, "FileCommitsCount", nil)
  104. return
  105. }
  106. page := ctx.QueryInt("page")
  107. if page <= 1 {
  108. page = 1
  109. }
  110. ctx.Data["Page"] = paginater.New(int(commitsCount), git.CommitsRangeSize, page, 5)
  111. commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(branchName, fileName, page)
  112. if err != nil {
  113. ctx.Handle(500, "CommitsByFileAndRange", err)
  114. return
  115. }
  116. commits = renderIssueLinks(commits, ctx.Repo.RepoLink)
  117. commits = models.ValidateCommitsWithEmails(commits)
  118. ctx.Data["Commits"] = commits
  119. ctx.Data["Username"] = ctx.Repo.Owner.Name
  120. ctx.Data["Reponame"] = ctx.Repo.Repository.Name
  121. ctx.Data["FileName"] = fileName
  122. ctx.Data["CommitCount"] = commitsCount
  123. ctx.Data["Branch"] = branchName
  124. ctx.HTML(200, tplCommits)
  125. }
  126. // Diff show different from current commit to previous commit
  127. func Diff(ctx *context.Context) {
  128. ctx.Data["PageIsDiff"] = true
  129. ctx.Data["RequireHighlightJS"] = true
  130. userName := ctx.Repo.Owner.Name
  131. repoName := ctx.Repo.Repository.Name
  132. commitID := ctx.Params(":sha")
  133. commit, err := ctx.Repo.GitRepo.GetCommit(commitID)
  134. if err != nil {
  135. if git.IsErrNotExist(err) {
  136. ctx.Handle(404, "Repo.GitRepo.GetCommit", err)
  137. } else {
  138. ctx.Handle(500, "Repo.GitRepo.GetCommit", err)
  139. }
  140. return
  141. }
  142. if len(commitID) != 40 {
  143. commitID = commit.ID.String()
  144. }
  145. diff, err := models.GetDiffCommit(models.RepoPath(userName, repoName),
  146. commitID, setting.Git.MaxGitDiffLines,
  147. setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles)
  148. if err != nil {
  149. ctx.Handle(404, "GetDiffCommit", err)
  150. return
  151. }
  152. parents := make([]string, commit.ParentCount())
  153. for i := 0; i < commit.ParentCount(); i++ {
  154. sha, err := commit.ParentID(i)
  155. parents[i] = sha.String()
  156. if err != nil {
  157. ctx.Handle(404, "repo.Diff", err)
  158. return
  159. }
  160. }
  161. ctx.Data["CommitID"] = commitID
  162. ctx.Data["Username"] = userName
  163. ctx.Data["Reponame"] = repoName
  164. ctx.Data["IsImageFile"] = commit.IsImageFile
  165. ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID)
  166. ctx.Data["Commit"] = commit
  167. ctx.Data["Author"] = models.ValidateCommitWithEmail(commit)
  168. ctx.Data["Diff"] = diff
  169. ctx.Data["Parents"] = parents
  170. ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
  171. ctx.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", commitID)
  172. if commit.ParentCount() > 0 {
  173. ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", parents[0])
  174. }
  175. ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "raw", commitID)
  176. ctx.HTML(200, tplDiff)
  177. }
  178. // RawDiff dumps diff results of repository in given commit ID to io.Writer
  179. func RawDiff(ctx *context.Context) {
  180. if err := models.GetRawDiff(
  181. models.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name),
  182. ctx.Params(":sha"),
  183. models.RawDiffType(ctx.Params(":ext")),
  184. ctx.Resp,
  185. ); err != nil {
  186. ctx.Handle(500, "GetRawDiff", err)
  187. return
  188. }
  189. }
  190. // CompareDiff show different from one commit to another commit
  191. func CompareDiff(ctx *context.Context) {
  192. ctx.Data["IsRepoToolbarCommits"] = true
  193. ctx.Data["IsDiffCompare"] = true
  194. userName := ctx.Repo.Owner.Name
  195. repoName := ctx.Repo.Repository.Name
  196. beforeCommitID := ctx.Params(":before")
  197. afterCommitID := ctx.Params(":after")
  198. commit, err := ctx.Repo.GitRepo.GetCommit(afterCommitID)
  199. if err != nil {
  200. ctx.Handle(404, "GetCommit", err)
  201. return
  202. }
  203. diff, err := models.GetDiffRange(models.RepoPath(userName, repoName), beforeCommitID,
  204. afterCommitID, setting.Git.MaxGitDiffLines,
  205. setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles)
  206. if err != nil {
  207. ctx.Handle(404, "GetDiffRange", err)
  208. return
  209. }
  210. commits, err := commit.CommitsBeforeUntil(beforeCommitID)
  211. if err != nil {
  212. ctx.Handle(500, "CommitsBeforeUntil", err)
  213. return
  214. }
  215. commits = models.ValidateCommitsWithEmails(commits)
  216. ctx.Data["CommitRepoLink"] = ctx.Repo.RepoLink
  217. ctx.Data["Commits"] = commits
  218. ctx.Data["CommitCount"] = commits.Len()
  219. ctx.Data["BeforeCommitID"] = beforeCommitID
  220. ctx.Data["AfterCommitID"] = afterCommitID
  221. ctx.Data["Username"] = userName
  222. ctx.Data["Reponame"] = repoName
  223. ctx.Data["IsImageFile"] = commit.IsImageFile
  224. ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + "..." + base.ShortSha(afterCommitID) + " · " + userName + "/" + repoName
  225. ctx.Data["Commit"] = commit
  226. ctx.Data["Diff"] = diff
  227. ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
  228. ctx.Data["SourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", afterCommitID)
  229. ctx.Data["BeforeSourcePath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "src", beforeCommitID)
  230. ctx.Data["RawPath"] = setting.AppSubURL + "/" + path.Join(userName, repoName, "raw", afterCommitID)
  231. ctx.HTML(200, tplDiff)
  232. }