gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright 2024 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package repo
  4. import (
  5. "net/http"
  6. "strings"
  7. user_model "code.gitea.io/gitea/models/user"
  8. "code.gitea.io/gitea/modules/gitrepo"
  9. api "code.gitea.io/gitea/modules/structs"
  10. "code.gitea.io/gitea/services/context"
  11. "code.gitea.io/gitea/services/convert"
  12. )
  13. // CompareDiff compare two branches or commits
  14. func CompareDiff(ctx *context.APIContext) {
  15. // swagger:operation GET /repos/{owner}/{repo}/compare/{basehead} repository repoCompareDiff
  16. // ---
  17. // summary: Get commit comparison information
  18. // produces:
  19. // - application/json
  20. // parameters:
  21. // - name: owner
  22. // in: path
  23. // description: owner of the repo
  24. // type: string
  25. // required: true
  26. // - name: repo
  27. // in: path
  28. // description: name of the repo
  29. // type: string
  30. // required: true
  31. // - name: basehead
  32. // in: path
  33. // description: compare two branches or commits
  34. // type: string
  35. // required: true
  36. // responses:
  37. // "200":
  38. // "$ref": "#/responses/Compare"
  39. // "404":
  40. // "$ref": "#/responses/notFound"
  41. if ctx.Repo.GitRepo == nil {
  42. var err error
  43. ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
  44. if err != nil {
  45. ctx.APIErrorInternal(err)
  46. return
  47. }
  48. }
  49. infoPath := ctx.PathParam("*")
  50. infos := []string{ctx.Repo.Repository.DefaultBranch, ctx.Repo.Repository.DefaultBranch}
  51. if infoPath != "" {
  52. infos = strings.SplitN(infoPath, "...", 2)
  53. if len(infos) != 2 {
  54. if infos = strings.SplitN(infoPath, "..", 2); len(infos) != 2 {
  55. infos = []string{ctx.Repo.Repository.DefaultBranch, infoPath}
  56. }
  57. }
  58. }
  59. compareResult, closer := parseCompareInfo(ctx, api.CreatePullRequestOption{Base: infos[0], Head: infos[1]})
  60. if ctx.Written() {
  61. return
  62. }
  63. defer closer()
  64. verification := ctx.FormString("verification") == "" || ctx.FormBool("verification")
  65. files := ctx.FormString("files") == "" || ctx.FormBool("files")
  66. apiCommits := make([]*api.Commit, 0, len(compareResult.compareInfo.Commits))
  67. userCache := make(map[string]*user_model.User)
  68. for i := 0; i < len(compareResult.compareInfo.Commits); i++ {
  69. apiCommit, err := convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, compareResult.compareInfo.Commits[i], userCache,
  70. convert.ToCommitOptions{
  71. Stat: true,
  72. Verification: verification,
  73. Files: files,
  74. })
  75. if err != nil {
  76. ctx.APIErrorInternal(err)
  77. return
  78. }
  79. apiCommits = append(apiCommits, apiCommit)
  80. }
  81. ctx.JSON(http.StatusOK, &api.Compare{
  82. TotalCommits: len(compareResult.compareInfo.Commits),
  83. Commits: apiCommits,
  84. })
  85. }