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.3 kB

11 years ago
10 years ago
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
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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. "github.com/Unknwon/com"
  9. "github.com/Unknwon/paginater"
  10. "github.com/gogits/gogs/models"
  11. "github.com/gogits/gogs/modules/base"
  12. "github.com/gogits/gogs/modules/git"
  13. "github.com/gogits/gogs/modules/middleware"
  14. "github.com/gogits/gogs/modules/setting"
  15. )
  16. const (
  17. COMMITS base.TplName = "repo/commits"
  18. DIFF base.TplName = "repo/diff"
  19. )
  20. func RefCommits(ctx *middleware.Context) {
  21. switch {
  22. case len(ctx.Repo.TreeName) == 0:
  23. Commits(ctx)
  24. case ctx.Repo.TreeName == "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. c.CommitMessage = c.CommitMessage
  35. newCommits.PushBack(c)
  36. }
  37. return newCommits
  38. }
  39. func Commits(ctx *middleware.Context) {
  40. ctx.Data["PageIsCommits"] = true
  41. userName := ctx.Repo.Owner.Name
  42. repoName := ctx.Repo.Repository.Name
  43. brs, err := ctx.Repo.GitRepo.GetBranches()
  44. if err != nil {
  45. ctx.Handle(500, "GetBranches", err)
  46. return
  47. } else if len(brs) == 0 {
  48. ctx.Handle(404, "GetBranches", nil)
  49. return
  50. }
  51. commitsCount, err := ctx.Repo.Commit.CommitsCount()
  52. if err != nil {
  53. ctx.Handle(500, "GetCommitsCount", err)
  54. return
  55. }
  56. page := ctx.QueryInt("page")
  57. if page <= 1 {
  58. page = 1
  59. }
  60. ctx.Data["Page"] = paginater.New(commitsCount, git.CommitsRangeSize, page, 5)
  61. // Both `git log branchName` and `git log commitId` work.
  62. commits, err := ctx.Repo.Commit.CommitsByRange(page)
  63. if err != nil {
  64. ctx.Handle(500, "CommitsByRange", err)
  65. return
  66. }
  67. commits = RenderIssueLinks(commits, ctx.Repo.RepoLink)
  68. commits = models.ValidateCommitsWithEmails(commits)
  69. ctx.Data["Commits"] = commits
  70. ctx.Data["Username"] = userName
  71. ctx.Data["Reponame"] = repoName
  72. ctx.Data["CommitCount"] = commitsCount
  73. ctx.HTML(200, COMMITS)
  74. }
  75. func SearchCommits(ctx *middleware.Context) {
  76. ctx.Data["PageIsCommits"] = true
  77. keyword := ctx.Query("q")
  78. if len(keyword) == 0 {
  79. ctx.Redirect(ctx.Repo.RepoLink + "/commits/" + ctx.Repo.BranchName)
  80. return
  81. }
  82. userName := ctx.Params(":username")
  83. repoName := ctx.Params(":reponame")
  84. brs, err := ctx.Repo.GitRepo.GetBranches()
  85. if err != nil {
  86. ctx.Handle(500, "GetBranches", err)
  87. return
  88. } else if len(brs) == 0 {
  89. ctx.Handle(404, "GetBranches", nil)
  90. return
  91. }
  92. commits, err := ctx.Repo.Commit.SearchCommits(keyword)
  93. if err != nil {
  94. ctx.Handle(500, "SearchCommits", err)
  95. return
  96. }
  97. commits = RenderIssueLinks(commits, ctx.Repo.RepoLink)
  98. commits = models.ValidateCommitsWithEmails(commits)
  99. ctx.Data["Keyword"] = keyword
  100. ctx.Data["Username"] = userName
  101. ctx.Data["Reponame"] = repoName
  102. ctx.Data["CommitCount"] = commits.Len()
  103. ctx.Data["Commits"] = commits
  104. ctx.HTML(200, COMMITS)
  105. }
  106. func FileHistory(ctx *middleware.Context) {
  107. ctx.Data["IsRepoToolbarCommits"] = true
  108. fileName := ctx.Repo.TreeName
  109. if len(fileName) == 0 {
  110. Commits(ctx)
  111. return
  112. }
  113. userName := ctx.Repo.Owner.Name
  114. repoName := ctx.Repo.Repository.Name
  115. branchName := ctx.Repo.BranchName
  116. brs, err := ctx.Repo.GitRepo.GetBranches()
  117. if err != nil {
  118. ctx.Handle(500, "GetBranches", err)
  119. return
  120. } else if len(brs) == 0 {
  121. ctx.Handle(404, "GetBranches", nil)
  122. return
  123. }
  124. commitsCount, err := ctx.Repo.GitRepo.FileCommitsCount(branchName, fileName)
  125. if err != nil {
  126. ctx.Handle(500, "repo.FileHistory(GetCommitsCount)", err)
  127. return
  128. } else if commitsCount == 0 {
  129. ctx.Handle(404, "repo.FileHistory", nil)
  130. return
  131. }
  132. // Calculate and validate page number.
  133. page := com.StrTo(ctx.Query("p")).MustInt()
  134. if page < 1 {
  135. page = 1
  136. }
  137. lastPage := page - 1
  138. if lastPage < 0 {
  139. lastPage = 0
  140. }
  141. nextPage := page + 1
  142. if nextPage*50 > commitsCount {
  143. nextPage = 0
  144. }
  145. commits, err := ctx.Repo.GitRepo.CommitsByFileAndRange(
  146. branchName, fileName, page)
  147. if err != nil {
  148. ctx.Handle(500, "repo.FileHistory(CommitsByRange)", err)
  149. return
  150. }
  151. commits = RenderIssueLinks(commits, ctx.Repo.RepoLink)
  152. commits = models.ValidateCommitsWithEmails(commits)
  153. ctx.Data["Commits"] = commits
  154. ctx.Data["Username"] = userName
  155. ctx.Data["Reponame"] = repoName
  156. ctx.Data["FileName"] = fileName
  157. ctx.Data["CommitCount"] = commitsCount
  158. ctx.Data["LastPageNum"] = lastPage
  159. ctx.Data["NextPageNum"] = nextPage
  160. ctx.HTML(200, COMMITS)
  161. }
  162. func Diff(ctx *middleware.Context) {
  163. ctx.Data["PageIsDiff"] = true
  164. userName := ctx.Repo.Owner.Name
  165. repoName := ctx.Repo.Repository.Name
  166. commitID := ctx.Repo.CommitID
  167. commit := ctx.Repo.Commit
  168. commit.CommitMessage = commit.CommitMessage
  169. diff, err := models.GetDiffCommit(models.RepoPath(userName, repoName),
  170. commitID, setting.Git.MaxGitDiffLines)
  171. if err != nil {
  172. ctx.Handle(404, "GetDiffCommit", err)
  173. return
  174. }
  175. isImageFile := func(name string) bool {
  176. blob, err := ctx.Repo.Commit.GetBlobByPath(name)
  177. if err != nil {
  178. return false
  179. }
  180. dataRc, err := blob.Data()
  181. if err != nil {
  182. return false
  183. }
  184. buf := make([]byte, 1024)
  185. n, _ := dataRc.Read(buf)
  186. if n > 0 {
  187. buf = buf[:n]
  188. }
  189. _, isImage := base.IsImageFile(buf)
  190. return isImage
  191. }
  192. parents := make([]string, commit.ParentCount())
  193. for i := 0; i < commit.ParentCount(); i++ {
  194. sha, err := commit.ParentId(i)
  195. parents[i] = sha.String()
  196. if err != nil {
  197. ctx.Handle(404, "repo.Diff", err)
  198. return
  199. }
  200. }
  201. ctx.Data["Username"] = userName
  202. ctx.Data["Reponame"] = repoName
  203. ctx.Data["IsImageFile"] = isImageFile
  204. ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID)
  205. ctx.Data["Commit"] = commit
  206. ctx.Data["Author"] = models.ValidateCommitWithEmail(commit)
  207. ctx.Data["Diff"] = diff
  208. ctx.Data["Parents"] = parents
  209. ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
  210. ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", commitID)
  211. if commit.ParentCount() > 0 {
  212. ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", parents[0])
  213. }
  214. ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "raw", commitID)
  215. ctx.HTML(200, DIFF)
  216. }
  217. func CompareDiff(ctx *middleware.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. if err != nil {
  232. ctx.Handle(404, "GetDiffRange", err)
  233. return
  234. }
  235. isImageFile := func(name string) bool {
  236. blob, err := commit.GetBlobByPath(name)
  237. if err != nil {
  238. return false
  239. }
  240. dataRc, err := blob.Data()
  241. if err != nil {
  242. return false
  243. }
  244. buf := make([]byte, 1024)
  245. n, _ := dataRc.Read(buf)
  246. if n > 0 {
  247. buf = buf[:n]
  248. }
  249. _, isImage := base.IsImageFile(buf)
  250. return isImage
  251. }
  252. commits, err := commit.CommitsBeforeUntil(beforeCommitID)
  253. if err != nil {
  254. ctx.Handle(500, "CommitsBeforeUntil", err)
  255. return
  256. }
  257. commits = models.ValidateCommitsWithEmails(commits)
  258. ctx.Data["CommitRepoLink"] = ctx.Repo.RepoLink
  259. ctx.Data["Commits"] = commits
  260. ctx.Data["CommitCount"] = commits.Len()
  261. ctx.Data["BeforeCommitID"] = beforeCommitID
  262. ctx.Data["AfterCommitID"] = afterCommitID
  263. ctx.Data["Username"] = userName
  264. ctx.Data["Reponame"] = repoName
  265. ctx.Data["IsImageFile"] = isImageFile
  266. ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + "..." + base.ShortSha(afterCommitID) + " · " + userName + "/" + repoName
  267. ctx.Data["Commit"] = commit
  268. ctx.Data["Diff"] = diff
  269. ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
  270. ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", afterCommitID)
  271. ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "src", beforeCommitID)
  272. ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(userName, repoName, "raw", afterCommitID)
  273. ctx.HTML(200, DIFF)
  274. }