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