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.

pull.go 17 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
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
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
10 years ago
10 years ago
10 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  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. "errors"
  8. "path"
  9. "strings"
  10. "github.com/Unknwon/com"
  11. "github.com/gogits/gogs/models"
  12. "github.com/gogits/gogs/modules/auth"
  13. "github.com/gogits/gogs/modules/base"
  14. "github.com/gogits/gogs/modules/git"
  15. "github.com/gogits/gogs/modules/log"
  16. "github.com/gogits/gogs/modules/middleware"
  17. "github.com/gogits/gogs/modules/setting"
  18. )
  19. const (
  20. FORK base.TplName = "repo/pulls/fork"
  21. COMPARE_PULL base.TplName = "repo/pulls/compare"
  22. PULL_COMMITS base.TplName = "repo/pulls/commits"
  23. PULL_FILES base.TplName = "repo/pulls/files"
  24. )
  25. func getForkRepository(ctx *middleware.Context) *models.Repository {
  26. forkRepo, err := models.GetRepositoryByID(ctx.ParamsInt64(":repoid"))
  27. if err != nil {
  28. if models.IsErrRepoNotExist(err) {
  29. ctx.Handle(404, "GetRepositoryByID", nil)
  30. } else {
  31. ctx.Handle(500, "GetRepositoryByID", err)
  32. }
  33. return nil
  34. }
  35. if !forkRepo.CanBeForked() {
  36. ctx.Handle(404, "getForkRepository", nil)
  37. return nil
  38. }
  39. ctx.Data["repo_name"] = forkRepo.Name
  40. ctx.Data["description"] = forkRepo.Description
  41. ctx.Data["IsPrivate"] = forkRepo.IsPrivate
  42. if err = forkRepo.GetOwner(); err != nil {
  43. ctx.Handle(500, "GetOwner", err)
  44. return nil
  45. }
  46. ctx.Data["ForkFrom"] = forkRepo.Owner.Name + "/" + forkRepo.Name
  47. if err := ctx.User.GetOrganizations(); err != nil {
  48. ctx.Handle(500, "GetOrganizations", err)
  49. return nil
  50. }
  51. ctx.Data["Orgs"] = ctx.User.Orgs
  52. return forkRepo
  53. }
  54. func Fork(ctx *middleware.Context) {
  55. ctx.Data["Title"] = ctx.Tr("new_fork")
  56. getForkRepository(ctx)
  57. if ctx.Written() {
  58. return
  59. }
  60. ctx.Data["ContextUser"] = ctx.User
  61. ctx.HTML(200, FORK)
  62. }
  63. func ForkPost(ctx *middleware.Context, form auth.CreateRepoForm) {
  64. ctx.Data["Title"] = ctx.Tr("new_fork")
  65. forkRepo := getForkRepository(ctx)
  66. if ctx.Written() {
  67. return
  68. }
  69. ctxUser := checkContextUser(ctx, form.Uid)
  70. if ctx.Written() {
  71. return
  72. }
  73. ctx.Data["ContextUser"] = ctxUser
  74. if ctx.HasError() {
  75. ctx.HTML(200, FORK)
  76. return
  77. }
  78. repo, has := models.HasForkedRepo(ctxUser.Id, forkRepo.ID)
  79. if has {
  80. ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name)
  81. return
  82. }
  83. // Check ownership of organization.
  84. if ctxUser.IsOrganization() {
  85. if !ctxUser.IsOwnedBy(ctx.User.Id) {
  86. ctx.Error(403)
  87. return
  88. }
  89. }
  90. repo, err := models.ForkRepository(ctxUser, forkRepo, form.RepoName, form.Description)
  91. if err != nil {
  92. ctx.Data["Err_RepoName"] = true
  93. switch {
  94. case models.IsErrRepoAlreadyExist(err):
  95. ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), FORK, &form)
  96. case models.IsErrNameReserved(err):
  97. ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), FORK, &form)
  98. case models.IsErrNamePatternNotAllowed(err):
  99. ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), FORK, &form)
  100. default:
  101. ctx.Handle(500, "ForkPost", err)
  102. }
  103. return
  104. }
  105. log.Trace("Repository forked[%d]: %s/%s", forkRepo.ID, ctxUser.Name, repo.Name)
  106. ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name)
  107. }
  108. func checkPullInfo(ctx *middleware.Context) *models.Issue {
  109. issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
  110. if err != nil {
  111. if models.IsErrIssueNotExist(err) {
  112. ctx.Handle(404, "GetIssueByIndex", err)
  113. } else {
  114. ctx.Handle(500, "GetIssueByIndex", err)
  115. }
  116. return nil
  117. }
  118. ctx.Data["Title"] = issue.Name
  119. ctx.Data["Issue"] = issue
  120. if !issue.IsPull {
  121. ctx.Handle(404, "ViewPullCommits", nil)
  122. return nil
  123. }
  124. if err = issue.GetPoster(); err != nil {
  125. ctx.Handle(500, "GetPoster", err)
  126. return nil
  127. } else if err = issue.GetPullRequest(); err != nil {
  128. ctx.Handle(500, "GetPullRequest", err)
  129. return nil
  130. } else if err = issue.GetHeadRepo(); err != nil {
  131. ctx.Handle(500, "GetHeadRepo", err)
  132. return nil
  133. }
  134. if ctx.IsSigned {
  135. // Update issue-user.
  136. if err = issue.ReadBy(ctx.User.Id); err != nil {
  137. ctx.Handle(500, "ReadBy", err)
  138. return nil
  139. }
  140. }
  141. return issue
  142. }
  143. func PrepareMergedViewPullInfo(ctx *middleware.Context, pull *models.Issue) {
  144. ctx.Data["HasMerged"] = true
  145. var err error
  146. if err = pull.GetMerger(); err != nil {
  147. ctx.Handle(500, "GetMerger", err)
  148. return
  149. }
  150. ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBranch
  151. ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.BaseBranch
  152. ctx.Data["NumCommits"], err = ctx.Repo.GitRepo.CommitsCountBetween(pull.MergeBase, pull.MergedCommitID)
  153. if err != nil {
  154. ctx.Handle(500, "Repo.GitRepo.CommitsCountBetween", err)
  155. return
  156. }
  157. ctx.Data["NumFiles"], err = ctx.Repo.GitRepo.FilesCountBetween(pull.MergeBase, pull.MergedCommitID)
  158. if err != nil {
  159. ctx.Handle(500, "Repo.GitRepo.FilesCountBetween", err)
  160. return
  161. }
  162. }
  163. func PrepareViewPullInfo(ctx *middleware.Context, pull *models.Issue) *git.PullRequestInfo {
  164. repo := ctx.Repo.Repository
  165. ctx.Data["HeadTarget"] = pull.HeadUserName + "/" + pull.HeadBranch
  166. ctx.Data["BaseTarget"] = ctx.Repo.Owner.Name + "/" + pull.BaseBranch
  167. var (
  168. headGitRepo *git.Repository
  169. err error
  170. )
  171. if err = pull.GetHeadRepo(); err != nil {
  172. ctx.Handle(500, "GetHeadRepo", err)
  173. return nil
  174. }
  175. if pull.HeadRepo != nil {
  176. headRepoPath, err := pull.HeadRepo.RepoPath()
  177. if err != nil {
  178. ctx.Handle(500, "HeadRepo.RepoPath", err)
  179. return nil
  180. }
  181. headGitRepo, err = git.OpenRepository(headRepoPath)
  182. if err != nil {
  183. ctx.Handle(500, "OpenRepository", err)
  184. return nil
  185. }
  186. }
  187. if pull.HeadRepo == nil || !headGitRepo.IsBranchExist(pull.HeadBranch) {
  188. ctx.Data["IsPullReuqestBroken"] = true
  189. ctx.Data["HeadTarget"] = "deleted"
  190. ctx.Data["NumCommits"] = 0
  191. ctx.Data["NumFiles"] = 0
  192. return nil
  193. }
  194. prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(repo.Owner.Name, repo.Name),
  195. pull.BaseBranch, pull.HeadBranch)
  196. if err != nil {
  197. ctx.Handle(500, "GetPullRequestInfo", err)
  198. return nil
  199. }
  200. ctx.Data["NumCommits"] = prInfo.Commits.Len()
  201. ctx.Data["NumFiles"] = prInfo.NumFiles
  202. return prInfo
  203. }
  204. func ViewPullCommits(ctx *middleware.Context) {
  205. ctx.Data["PageIsPullCommits"] = true
  206. pull := checkPullInfo(ctx)
  207. if ctx.Written() {
  208. return
  209. }
  210. ctx.Data["Username"] = pull.HeadUserName
  211. ctx.Data["Reponame"] = pull.HeadRepo.Name
  212. var commits *list.List
  213. if pull.HasMerged {
  214. PrepareMergedViewPullInfo(ctx, pull)
  215. if ctx.Written() {
  216. return
  217. }
  218. startCommit, err := ctx.Repo.GitRepo.GetCommit(pull.MergeBase)
  219. if err != nil {
  220. ctx.Handle(500, "Repo.GitRepo.GetCommit", err)
  221. return
  222. }
  223. endCommit, err := ctx.Repo.GitRepo.GetCommit(pull.MergedCommitID)
  224. if err != nil {
  225. ctx.Handle(500, "Repo.GitRepo.GetCommit", err)
  226. return
  227. }
  228. commits, err = ctx.Repo.GitRepo.CommitsBetween(endCommit, startCommit)
  229. if err != nil {
  230. ctx.Handle(500, "Repo.GitRepo.CommitsBetween", err)
  231. return
  232. }
  233. } else {
  234. prInfo := PrepareViewPullInfo(ctx, pull)
  235. if ctx.Written() {
  236. return
  237. } else if prInfo == nil {
  238. ctx.Handle(404, "ViewPullCommits", nil)
  239. return
  240. }
  241. commits = prInfo.Commits
  242. }
  243. commits = models.ValidateCommitsWithEmails(commits)
  244. ctx.Data["Commits"] = commits
  245. ctx.Data["CommitCount"] = commits.Len()
  246. ctx.HTML(200, PULL_COMMITS)
  247. }
  248. func ViewPullFiles(ctx *middleware.Context) {
  249. ctx.Data["PageIsPullFiles"] = true
  250. pull := checkPullInfo(ctx)
  251. if ctx.Written() {
  252. return
  253. }
  254. var (
  255. diffRepoPath string
  256. startCommitID string
  257. endCommitID string
  258. gitRepo *git.Repository
  259. )
  260. if pull.HasMerged {
  261. PrepareMergedViewPullInfo(ctx, pull)
  262. if ctx.Written() {
  263. return
  264. }
  265. diffRepoPath = ctx.Repo.GitRepo.Path
  266. startCommitID = pull.MergeBase
  267. endCommitID = pull.MergedCommitID
  268. gitRepo = ctx.Repo.GitRepo
  269. } else {
  270. prInfo := PrepareViewPullInfo(ctx, pull)
  271. if ctx.Written() {
  272. return
  273. } else if prInfo == nil {
  274. ctx.Handle(404, "ViewPullFiles", nil)
  275. return
  276. }
  277. headRepoPath := models.RepoPath(pull.HeadUserName, pull.HeadRepo.Name)
  278. headGitRepo, err := git.OpenRepository(headRepoPath)
  279. if err != nil {
  280. ctx.Handle(500, "OpenRepository", err)
  281. return
  282. }
  283. headCommitID, err := headGitRepo.GetCommitIdOfBranch(pull.HeadBranch)
  284. if err != nil {
  285. ctx.Handle(500, "GetCommitIdOfBranch", err)
  286. return
  287. }
  288. diffRepoPath = headRepoPath
  289. startCommitID = prInfo.MergeBase
  290. endCommitID = headCommitID
  291. gitRepo = headGitRepo
  292. }
  293. diff, err := models.GetDiffRange(diffRepoPath,
  294. startCommitID, endCommitID, setting.Git.MaxGitDiffLines)
  295. if err != nil {
  296. ctx.Handle(500, "GetDiffRange", err)
  297. return
  298. }
  299. ctx.Data["Diff"] = diff
  300. ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
  301. commit, err := gitRepo.GetCommit(endCommitID)
  302. if err != nil {
  303. ctx.Handle(500, "GetCommit", err)
  304. return
  305. }
  306. headTarget := path.Join(pull.HeadUserName, pull.HeadRepo.Name)
  307. ctx.Data["Username"] = pull.HeadUserName
  308. ctx.Data["Reponame"] = pull.HeadRepo.Name
  309. ctx.Data["IsImageFile"] = commit.IsImageFile
  310. ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", endCommitID)
  311. ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", startCommitID)
  312. ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "raw", endCommitID)
  313. ctx.HTML(200, PULL_FILES)
  314. }
  315. func MergePullRequest(ctx *middleware.Context) {
  316. issue := checkPullInfo(ctx)
  317. if ctx.Written() {
  318. return
  319. }
  320. if issue.IsClosed {
  321. ctx.Handle(404, "MergePullRequest", nil)
  322. return
  323. }
  324. pr, err := models.GetPullRequestByIssueID(issue.ID)
  325. if err != nil {
  326. if models.IsErrPullRequestNotExist(err) {
  327. ctx.Handle(404, "GetPullRequestByIssueID", nil)
  328. } else {
  329. ctx.Handle(500, "GetPullRequestByIssueID", err)
  330. }
  331. return
  332. }
  333. if !pr.CanAutoMerge() || pr.HasMerged {
  334. ctx.Handle(404, "MergePullRequest", nil)
  335. return
  336. }
  337. pr.Issue = issue
  338. pr.Issue.Repo = ctx.Repo.Repository
  339. if err = pr.Merge(ctx.User, ctx.Repo.GitRepo); err != nil {
  340. ctx.Handle(500, "Merge", err)
  341. return
  342. }
  343. log.Trace("Pull request merged: %d", pr.ID)
  344. ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pr.Index))
  345. }
  346. func ParseCompareInfo(ctx *middleware.Context) (*models.User, *models.Repository, *git.Repository, *git.PullRequestInfo, string, string) {
  347. // Get compare branch information.
  348. infos := strings.Split(ctx.Params("*"), "...")
  349. if len(infos) != 2 {
  350. ctx.Handle(404, "CompareAndPullRequest", nil)
  351. return nil, nil, nil, nil, "", ""
  352. }
  353. baseBranch := infos[0]
  354. ctx.Data["BaseBranch"] = baseBranch
  355. headInfos := strings.Split(infos[1], ":")
  356. if len(headInfos) != 2 {
  357. ctx.Handle(404, "CompareAndPullRequest", nil)
  358. return nil, nil, nil, nil, "", ""
  359. }
  360. headUsername := headInfos[0]
  361. headBranch := headInfos[1]
  362. ctx.Data["HeadBranch"] = headBranch
  363. headUser, err := models.GetUserByName(headUsername)
  364. if err != nil {
  365. if models.IsErrUserNotExist(err) {
  366. ctx.Handle(404, "GetUserByName", nil)
  367. } else {
  368. ctx.Handle(500, "GetUserByName", err)
  369. }
  370. return nil, nil, nil, nil, "", ""
  371. }
  372. repo := ctx.Repo.Repository
  373. // Check if base branch is valid.
  374. if !ctx.Repo.GitRepo.IsBranchExist(baseBranch) {
  375. ctx.Handle(404, "IsBranchExist", nil)
  376. return nil, nil, nil, nil, "", ""
  377. }
  378. // Check if current user has fork of repository.
  379. headRepo, has := models.HasForkedRepo(headUser.Id, repo.ID)
  380. if !has || (!ctx.User.IsAdminOfRepo(headRepo) && !ctx.User.IsAdmin) {
  381. ctx.Handle(404, "HasForkedRepo", nil)
  382. return nil, nil, nil, nil, "", ""
  383. }
  384. headGitRepo, err := git.OpenRepository(models.RepoPath(headUser.Name, headRepo.Name))
  385. if err != nil {
  386. ctx.Handle(500, "OpenRepository", err)
  387. return nil, nil, nil, nil, "", ""
  388. }
  389. // Check if head branch is valid.
  390. if !headGitRepo.IsBranchExist(headBranch) {
  391. ctx.Handle(404, "IsBranchExist", nil)
  392. return nil, nil, nil, nil, "", ""
  393. }
  394. headBranches, err := headGitRepo.GetBranches()
  395. if err != nil {
  396. ctx.Handle(500, "GetBranches", err)
  397. return nil, nil, nil, nil, "", ""
  398. }
  399. ctx.Data["HeadBranches"] = headBranches
  400. prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(repo.Owner.Name, repo.Name), baseBranch, headBranch)
  401. if err != nil {
  402. ctx.Handle(500, "GetPullRequestInfo", err)
  403. return nil, nil, nil, nil, "", ""
  404. }
  405. ctx.Data["BeforeCommitID"] = prInfo.MergeBase
  406. return headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch
  407. }
  408. func PrepareCompareDiff(
  409. ctx *middleware.Context,
  410. headUser *models.User,
  411. headRepo *models.Repository,
  412. headGitRepo *git.Repository,
  413. prInfo *git.PullRequestInfo,
  414. baseBranch, headBranch string) bool {
  415. var (
  416. repo = ctx.Repo.Repository
  417. err error
  418. )
  419. // Get diff information.
  420. ctx.Data["CommitRepoLink"], err = headRepo.RepoLink()
  421. if err != nil {
  422. ctx.Handle(500, "RepoLink", err)
  423. return false
  424. }
  425. headCommitID, err := headGitRepo.GetCommitIdOfBranch(headBranch)
  426. if err != nil {
  427. ctx.Handle(500, "GetCommitIdOfBranch", err)
  428. return false
  429. }
  430. ctx.Data["AfterCommitID"] = headCommitID
  431. if headCommitID == prInfo.MergeBase {
  432. ctx.Data["IsNothingToCompare"] = true
  433. return true
  434. }
  435. diff, err := models.GetDiffRange(models.RepoPath(headUser.Name, headRepo.Name),
  436. prInfo.MergeBase, headCommitID, setting.Git.MaxGitDiffLines)
  437. if err != nil {
  438. ctx.Handle(500, "GetDiffRange", err)
  439. return false
  440. }
  441. ctx.Data["Diff"] = diff
  442. ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
  443. headCommit, err := headGitRepo.GetCommit(headCommitID)
  444. if err != nil {
  445. ctx.Handle(500, "GetCommit", err)
  446. return false
  447. }
  448. prInfo.Commits = models.ValidateCommitsWithEmails(prInfo.Commits)
  449. ctx.Data["Commits"] = prInfo.Commits
  450. ctx.Data["CommitCount"] = prInfo.Commits.Len()
  451. ctx.Data["Username"] = headUser.Name
  452. ctx.Data["Reponame"] = headRepo.Name
  453. ctx.Data["IsImageFile"] = headCommit.IsImageFile
  454. headTarget := path.Join(headUser.Name, repo.Name)
  455. ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", headCommitID)
  456. ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", prInfo.MergeBase)
  457. ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "raw", headCommitID)
  458. return false
  459. }
  460. func CompareAndPullRequest(ctx *middleware.Context) {
  461. ctx.Data["Title"] = ctx.Tr("repo.pulls.compare_changes")
  462. ctx.Data["PageIsComparePull"] = true
  463. ctx.Data["IsDiffCompare"] = true
  464. renderAttachmentSettings(ctx)
  465. headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch := ParseCompareInfo(ctx)
  466. if ctx.Written() {
  467. return
  468. }
  469. pr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch)
  470. if err != nil {
  471. if !models.IsErrPullRequestNotExist(err) {
  472. ctx.Handle(500, "GetUnmergedPullRequest", err)
  473. return
  474. }
  475. } else {
  476. ctx.Data["HasPullRequest"] = true
  477. ctx.Data["PullRequest"] = pr
  478. ctx.HTML(200, COMPARE_PULL)
  479. return
  480. }
  481. nothingToCompare := PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch)
  482. if ctx.Written() {
  483. return
  484. }
  485. if !nothingToCompare {
  486. // Setup information for new form.
  487. RetrieveRepoMetas(ctx, ctx.Repo.Repository)
  488. if ctx.Written() {
  489. return
  490. }
  491. }
  492. ctx.HTML(200, COMPARE_PULL)
  493. }
  494. func CompareAndPullRequestPost(ctx *middleware.Context, form auth.CreateIssueForm) {
  495. ctx.Data["Title"] = ctx.Tr("repo.pulls.compare_changes")
  496. ctx.Data["PageIsComparePull"] = true
  497. ctx.Data["IsDiffCompare"] = true
  498. renderAttachmentSettings(ctx)
  499. var (
  500. repo = ctx.Repo.Repository
  501. attachments []string
  502. )
  503. headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch := ParseCompareInfo(ctx)
  504. if ctx.Written() {
  505. return
  506. }
  507. patch, err := headGitRepo.GetPatch(prInfo.MergeBase, headBranch)
  508. if err != nil {
  509. ctx.Handle(500, "GetPatch", err)
  510. return
  511. }
  512. labelIDs, milestoneID, assigneeID := ValidateRepoMetas(ctx, form)
  513. if ctx.Written() {
  514. return
  515. }
  516. if setting.AttachmentEnabled {
  517. attachments = form.Attachments
  518. }
  519. if ctx.HasError() {
  520. ctx.HTML(200, COMPARE_PULL)
  521. return
  522. }
  523. pull := &models.Issue{
  524. RepoID: repo.ID,
  525. Index: repo.NextIssueIndex(),
  526. Name: form.Title,
  527. PosterID: ctx.User.Id,
  528. Poster: ctx.User,
  529. MilestoneID: milestoneID,
  530. AssigneeID: assigneeID,
  531. IsPull: true,
  532. Content: form.Content,
  533. }
  534. if err := models.NewPullRequest(repo, pull, labelIDs, attachments, &models.PullRequest{
  535. HeadRepoID: headRepo.ID,
  536. BaseRepoID: repo.ID,
  537. HeadUserName: headUser.Name,
  538. HeadBranch: headBranch,
  539. BaseBranch: baseBranch,
  540. MergeBase: prInfo.MergeBase,
  541. Type: models.PULL_REQUEST_GOGS,
  542. }, patch); err != nil {
  543. ctx.Handle(500, "NewPullRequest", err)
  544. return
  545. }
  546. log.Trace("Pull request created: %d/%d", repo.ID, pull.ID)
  547. ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pull.Index))
  548. }
  549. func TriggerTask(ctx *middleware.Context) {
  550. _, repo := parseOwnerAndRepo(ctx)
  551. if ctx.Written() {
  552. return
  553. }
  554. branch := ctx.Query("branch")
  555. if len(branch) == 0 {
  556. ctx.Handle(422, "TriggerTask", errors.New("branch is empty"))
  557. return
  558. }
  559. log.Trace("TriggerTask[%d].(new request): %s", repo.ID, branch)
  560. go models.HookQueue.Add(repo.ID)
  561. go models.AddTestPullRequestTask(repo.ID, branch)
  562. ctx.Status(202)
  563. }