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
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  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. headGitRepo, err = git.OpenRepository(pull.HeadRepo.RepoPath())
  177. if err != nil {
  178. ctx.Handle(500, "OpenRepository", err)
  179. return nil
  180. }
  181. }
  182. if pull.HeadRepo == nil || !headGitRepo.IsBranchExist(pull.HeadBranch) {
  183. ctx.Data["IsPullReuqestBroken"] = true
  184. ctx.Data["HeadTarget"] = "deleted"
  185. ctx.Data["NumCommits"] = 0
  186. ctx.Data["NumFiles"] = 0
  187. return nil
  188. }
  189. prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(repo.Owner.Name, repo.Name),
  190. pull.BaseBranch, pull.HeadBranch)
  191. if err != nil {
  192. ctx.Handle(500, "GetPullRequestInfo", err)
  193. return nil
  194. }
  195. ctx.Data["NumCommits"] = prInfo.Commits.Len()
  196. ctx.Data["NumFiles"] = prInfo.NumFiles
  197. return prInfo
  198. }
  199. func ViewPullCommits(ctx *middleware.Context) {
  200. ctx.Data["PageIsPullCommits"] = true
  201. pull := checkPullInfo(ctx)
  202. if ctx.Written() {
  203. return
  204. }
  205. ctx.Data["Username"] = pull.HeadUserName
  206. ctx.Data["Reponame"] = pull.HeadRepo.Name
  207. var commits *list.List
  208. if pull.HasMerged {
  209. PrepareMergedViewPullInfo(ctx, pull)
  210. if ctx.Written() {
  211. return
  212. }
  213. startCommit, err := ctx.Repo.GitRepo.GetCommit(pull.MergeBase)
  214. if err != nil {
  215. ctx.Handle(500, "Repo.GitRepo.GetCommit", err)
  216. return
  217. }
  218. endCommit, err := ctx.Repo.GitRepo.GetCommit(pull.MergedCommitID)
  219. if err != nil {
  220. ctx.Handle(500, "Repo.GitRepo.GetCommit", err)
  221. return
  222. }
  223. commits, err = ctx.Repo.GitRepo.CommitsBetween(endCommit, startCommit)
  224. if err != nil {
  225. ctx.Handle(500, "Repo.GitRepo.CommitsBetween", err)
  226. return
  227. }
  228. } else {
  229. prInfo := PrepareViewPullInfo(ctx, pull)
  230. if ctx.Written() {
  231. return
  232. } else if prInfo == nil {
  233. ctx.Handle(404, "ViewPullCommits", nil)
  234. return
  235. }
  236. commits = prInfo.Commits
  237. }
  238. commits = models.ValidateCommitsWithEmails(commits)
  239. ctx.Data["Commits"] = commits
  240. ctx.Data["CommitCount"] = commits.Len()
  241. ctx.HTML(200, PULL_COMMITS)
  242. }
  243. func ViewPullFiles(ctx *middleware.Context) {
  244. ctx.Data["PageIsPullFiles"] = true
  245. pull := checkPullInfo(ctx)
  246. if ctx.Written() {
  247. return
  248. }
  249. var (
  250. diffRepoPath string
  251. startCommitID string
  252. endCommitID string
  253. gitRepo *git.Repository
  254. )
  255. if pull.HasMerged {
  256. PrepareMergedViewPullInfo(ctx, pull)
  257. if ctx.Written() {
  258. return
  259. }
  260. diffRepoPath = ctx.Repo.GitRepo.Path
  261. startCommitID = pull.MergeBase
  262. endCommitID = pull.MergedCommitID
  263. gitRepo = ctx.Repo.GitRepo
  264. } else {
  265. prInfo := PrepareViewPullInfo(ctx, pull)
  266. if ctx.Written() {
  267. return
  268. } else if prInfo == nil {
  269. ctx.Handle(404, "ViewPullFiles", nil)
  270. return
  271. }
  272. headRepoPath := models.RepoPath(pull.HeadUserName, pull.HeadRepo.Name)
  273. headGitRepo, err := git.OpenRepository(headRepoPath)
  274. if err != nil {
  275. ctx.Handle(500, "OpenRepository", err)
  276. return
  277. }
  278. headCommitID, err := headGitRepo.GetCommitIdOfBranch(pull.HeadBranch)
  279. if err != nil {
  280. ctx.Handle(500, "GetCommitIdOfBranch", err)
  281. return
  282. }
  283. diffRepoPath = headRepoPath
  284. startCommitID = prInfo.MergeBase
  285. endCommitID = headCommitID
  286. gitRepo = headGitRepo
  287. }
  288. diff, err := models.GetDiffRange(diffRepoPath,
  289. startCommitID, endCommitID, setting.Git.MaxGitDiffLines)
  290. if err != nil {
  291. ctx.Handle(500, "GetDiffRange", err)
  292. return
  293. }
  294. ctx.Data["Diff"] = diff
  295. ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
  296. commit, err := gitRepo.GetCommit(endCommitID)
  297. if err != nil {
  298. ctx.Handle(500, "GetCommit", err)
  299. return
  300. }
  301. headTarget := path.Join(pull.HeadUserName, pull.HeadRepo.Name)
  302. ctx.Data["Username"] = pull.HeadUserName
  303. ctx.Data["Reponame"] = pull.HeadRepo.Name
  304. ctx.Data["IsImageFile"] = commit.IsImageFile
  305. ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", endCommitID)
  306. ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", startCommitID)
  307. ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "raw", endCommitID)
  308. ctx.HTML(200, PULL_FILES)
  309. }
  310. func MergePullRequest(ctx *middleware.Context) {
  311. issue := checkPullInfo(ctx)
  312. if ctx.Written() {
  313. return
  314. }
  315. if issue.IsClosed {
  316. ctx.Handle(404, "MergePullRequest", nil)
  317. return
  318. }
  319. pr, err := models.GetPullRequestByIssueID(issue.ID)
  320. if err != nil {
  321. if models.IsErrPullRequestNotExist(err) {
  322. ctx.Handle(404, "GetPullRequestByIssueID", nil)
  323. } else {
  324. ctx.Handle(500, "GetPullRequestByIssueID", err)
  325. }
  326. return
  327. }
  328. if !pr.CanAutoMerge() || pr.HasMerged {
  329. ctx.Handle(404, "MergePullRequest", nil)
  330. return
  331. }
  332. pr.Issue = issue
  333. pr.Issue.Repo = ctx.Repo.Repository
  334. if err = pr.Merge(ctx.User, ctx.Repo.GitRepo); err != nil {
  335. ctx.Handle(500, "Merge", err)
  336. return
  337. }
  338. log.Trace("Pull request merged: %d", pr.ID)
  339. ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pr.Index))
  340. }
  341. func ParseCompareInfo(ctx *middleware.Context) (*models.User, *models.Repository, *git.Repository, *git.PullRequestInfo, string, string) {
  342. // Get compare branch information.
  343. infos := strings.Split(ctx.Params("*"), "...")
  344. if len(infos) != 2 {
  345. ctx.Handle(404, "CompareAndPullRequest", nil)
  346. return nil, nil, nil, nil, "", ""
  347. }
  348. baseBranch := infos[0]
  349. ctx.Data["BaseBranch"] = baseBranch
  350. headInfos := strings.Split(infos[1], ":")
  351. if len(headInfos) != 2 {
  352. ctx.Handle(404, "CompareAndPullRequest", nil)
  353. return nil, nil, nil, nil, "", ""
  354. }
  355. headUsername := headInfos[0]
  356. headBranch := headInfos[1]
  357. ctx.Data["HeadBranch"] = headBranch
  358. headUser, err := models.GetUserByName(headUsername)
  359. if err != nil {
  360. if models.IsErrUserNotExist(err) {
  361. ctx.Handle(404, "GetUserByName", nil)
  362. } else {
  363. ctx.Handle(500, "GetUserByName", err)
  364. }
  365. return nil, nil, nil, nil, "", ""
  366. }
  367. repo := ctx.Repo.Repository
  368. // Check if base branch is valid.
  369. if !ctx.Repo.GitRepo.IsBranchExist(baseBranch) {
  370. ctx.Handle(404, "IsBranchExist", nil)
  371. return nil, nil, nil, nil, "", ""
  372. }
  373. // Check if current user has fork of repository.
  374. headRepo, has := models.HasForkedRepo(headUser.Id, repo.ID)
  375. if !has || (!ctx.User.IsAdminOfRepo(headRepo) && !ctx.User.IsAdmin) {
  376. ctx.Handle(404, "HasForkedRepo", nil)
  377. return nil, nil, nil, nil, "", ""
  378. }
  379. headGitRepo, err := git.OpenRepository(models.RepoPath(headUser.Name, headRepo.Name))
  380. if err != nil {
  381. ctx.Handle(500, "OpenRepository", err)
  382. return nil, nil, nil, nil, "", ""
  383. }
  384. // Check if head branch is valid.
  385. if !headGitRepo.IsBranchExist(headBranch) {
  386. ctx.Handle(404, "IsBranchExist", nil)
  387. return nil, nil, nil, nil, "", ""
  388. }
  389. headBranches, err := headGitRepo.GetBranches()
  390. if err != nil {
  391. ctx.Handle(500, "GetBranches", err)
  392. return nil, nil, nil, nil, "", ""
  393. }
  394. ctx.Data["HeadBranches"] = headBranches
  395. prInfo, err := headGitRepo.GetPullRequestInfo(models.RepoPath(repo.Owner.Name, repo.Name), baseBranch, headBranch)
  396. if err != nil {
  397. ctx.Handle(500, "GetPullRequestInfo", err)
  398. return nil, nil, nil, nil, "", ""
  399. }
  400. ctx.Data["BeforeCommitID"] = prInfo.MergeBase
  401. return headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch
  402. }
  403. func PrepareCompareDiff(
  404. ctx *middleware.Context,
  405. headUser *models.User,
  406. headRepo *models.Repository,
  407. headGitRepo *git.Repository,
  408. prInfo *git.PullRequestInfo,
  409. baseBranch, headBranch string) bool {
  410. var (
  411. repo = ctx.Repo.Repository
  412. err error
  413. )
  414. // Get diff information.
  415. ctx.Data["CommitRepoLink"] = headRepo.RepoLink()
  416. headCommitID, err := headGitRepo.GetCommitIdOfBranch(headBranch)
  417. if err != nil {
  418. ctx.Handle(500, "GetCommitIdOfBranch", err)
  419. return false
  420. }
  421. ctx.Data["AfterCommitID"] = headCommitID
  422. if headCommitID == prInfo.MergeBase {
  423. ctx.Data["IsNothingToCompare"] = true
  424. return true
  425. }
  426. diff, err := models.GetDiffRange(models.RepoPath(headUser.Name, headRepo.Name),
  427. prInfo.MergeBase, headCommitID, setting.Git.MaxGitDiffLines)
  428. if err != nil {
  429. ctx.Handle(500, "GetDiffRange", err)
  430. return false
  431. }
  432. ctx.Data["Diff"] = diff
  433. ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
  434. headCommit, err := headGitRepo.GetCommit(headCommitID)
  435. if err != nil {
  436. ctx.Handle(500, "GetCommit", err)
  437. return false
  438. }
  439. prInfo.Commits = models.ValidateCommitsWithEmails(prInfo.Commits)
  440. ctx.Data["Commits"] = prInfo.Commits
  441. ctx.Data["CommitCount"] = prInfo.Commits.Len()
  442. ctx.Data["Username"] = headUser.Name
  443. ctx.Data["Reponame"] = headRepo.Name
  444. ctx.Data["IsImageFile"] = headCommit.IsImageFile
  445. headTarget := path.Join(headUser.Name, repo.Name)
  446. ctx.Data["SourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", headCommitID)
  447. ctx.Data["BeforeSourcePath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "src", prInfo.MergeBase)
  448. ctx.Data["RawPath"] = setting.AppSubUrl + "/" + path.Join(headTarget, "raw", headCommitID)
  449. return false
  450. }
  451. func CompareAndPullRequest(ctx *middleware.Context) {
  452. ctx.Data["Title"] = ctx.Tr("repo.pulls.compare_changes")
  453. ctx.Data["PageIsComparePull"] = true
  454. ctx.Data["IsDiffCompare"] = true
  455. renderAttachmentSettings(ctx)
  456. headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch := ParseCompareInfo(ctx)
  457. if ctx.Written() {
  458. return
  459. }
  460. pr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch)
  461. if err != nil {
  462. if !models.IsErrPullRequestNotExist(err) {
  463. ctx.Handle(500, "GetUnmergedPullRequest", err)
  464. return
  465. }
  466. } else {
  467. ctx.Data["HasPullRequest"] = true
  468. ctx.Data["PullRequest"] = pr
  469. ctx.HTML(200, COMPARE_PULL)
  470. return
  471. }
  472. nothingToCompare := PrepareCompareDiff(ctx, headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch)
  473. if ctx.Written() {
  474. return
  475. }
  476. if !nothingToCompare {
  477. // Setup information for new form.
  478. RetrieveRepoMetas(ctx, ctx.Repo.Repository)
  479. if ctx.Written() {
  480. return
  481. }
  482. }
  483. ctx.HTML(200, COMPARE_PULL)
  484. }
  485. func CompareAndPullRequestPost(ctx *middleware.Context, form auth.CreateIssueForm) {
  486. ctx.Data["Title"] = ctx.Tr("repo.pulls.compare_changes")
  487. ctx.Data["PageIsComparePull"] = true
  488. ctx.Data["IsDiffCompare"] = true
  489. renderAttachmentSettings(ctx)
  490. var (
  491. repo = ctx.Repo.Repository
  492. attachments []string
  493. )
  494. headUser, headRepo, headGitRepo, prInfo, baseBranch, headBranch := ParseCompareInfo(ctx)
  495. if ctx.Written() {
  496. return
  497. }
  498. patch, err := headGitRepo.GetPatch(prInfo.MergeBase, headBranch)
  499. if err != nil {
  500. ctx.Handle(500, "GetPatch", err)
  501. return
  502. }
  503. labelIDs, milestoneID, assigneeID := ValidateRepoMetas(ctx, form)
  504. if ctx.Written() {
  505. return
  506. }
  507. if setting.AttachmentEnabled {
  508. attachments = form.Attachments
  509. }
  510. if ctx.HasError() {
  511. ctx.HTML(200, COMPARE_PULL)
  512. return
  513. }
  514. pull := &models.Issue{
  515. RepoID: repo.ID,
  516. Index: repo.NextIssueIndex(),
  517. Name: form.Title,
  518. PosterID: ctx.User.Id,
  519. Poster: ctx.User,
  520. MilestoneID: milestoneID,
  521. AssigneeID: assigneeID,
  522. IsPull: true,
  523. Content: form.Content,
  524. }
  525. if err := models.NewPullRequest(repo, pull, labelIDs, attachments, &models.PullRequest{
  526. HeadRepoID: headRepo.ID,
  527. BaseRepoID: repo.ID,
  528. HeadUserName: headUser.Name,
  529. HeadBranch: headBranch,
  530. BaseBranch: baseBranch,
  531. MergeBase: prInfo.MergeBase,
  532. Type: models.PULL_REQUEST_GOGS,
  533. }, patch); err != nil {
  534. ctx.Handle(500, "NewPullRequest", err)
  535. return
  536. }
  537. log.Trace("Pull request created: %d/%d", repo.ID, pull.ID)
  538. ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pull.Index))
  539. }
  540. func TriggerTask(ctx *middleware.Context) {
  541. _, repo := parseOwnerAndRepo(ctx)
  542. if ctx.Written() {
  543. return
  544. }
  545. branch := ctx.Query("branch")
  546. if len(branch) == 0 {
  547. ctx.Handle(422, "TriggerTask", errors.New("branch is empty"))
  548. return
  549. }
  550. log.Trace("TriggerTask[%d].(new request): %s", repo.ID, branch)
  551. go models.HookQueue.Add(repo.ID)
  552. go models.AddTestPullRequestTask(repo.ID, branch)
  553. ctx.Status(202)
  554. }