diff --git a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala index 68815f9..f77fb8e 100644 --- a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala +++ b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala @@ -248,6 +248,7 @@ }) get("/:owner/:repository/compare")(referrersOnly { forkedRepository => + val headBranch:Option[String] = params.get("head") (forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match { case (Some(originUserName), Some(originRepositoryName)) => { getRepository(originUserName, originRepositoryName, context.baseUrl).map { originRepository => @@ -255,8 +256,8 @@ Git.open(getRepositoryDir(originUserName, originRepositoryName)), Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name)) ){ (oldGit, newGit) => - val oldBranch = JGitUtil.getDefaultBranch(oldGit, originRepository).get._2 - val newBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository).get._2 + val newBranch = headBranch.getOrElse(JGitUtil.getDefaultBranch(newGit, forkedRepository).get._2) + val oldBranch = originRepository.branchList.find( _ == newBranch).getOrElse(JGitUtil.getDefaultBranch(oldGit, originRepository).get._2) redirect(s"/${forkedRepository.owner}/${forkedRepository.name}/compare/${originUserName}:${oldBranch}...${newBranch}") } @@ -265,7 +266,7 @@ case _ => { using(Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))){ git => JGitUtil.getDefaultBranch(git, forkedRepository).map { case (_, defaultBranch) => - redirect(s"/${forkedRepository.owner}/${forkedRepository.name}/compare/${defaultBranch}...${defaultBranch}") + redirect(s"/${forkedRepository.owner}/${forkedRepository.name}/compare/${defaultBranch}...${headBranch.getOrElse(defaultBranch)}") } getOrElse { redirect(s"/${forkedRepository.owner}/${forkedRepository.name}") } diff --git a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala index 411a58d..03183bf 100644 --- a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala +++ b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala @@ -525,6 +525,7 @@ }, // groups of current user new JGitUtil.CommitInfo(lastModifiedCommit), // last modified commit files, readme, hasWritePermission(repository.owner, repository.name, context.loginAccount), + getPullRequestFromBranch(repository.owner, repository.name, revstr, repository.repository.defaultBranch), flash.get("info"), flash.get("error")) } } getOrElse NotFound diff --git a/src/main/scala/gitbucket/core/service/PullRequestService.scala b/src/main/scala/gitbucket/core/service/PullRequestService.scala index a6f4a2a..67db3c8 100644 --- a/src/main/scala/gitbucket/core/service/PullRequestService.scala +++ b/src/main/scala/gitbucket/core/service/PullRequestService.scala @@ -84,6 +84,28 @@ .list /** + * for repository viewer. + * 1. find pull request from from `branch` to othre branch on same repository + * 1. return if exists pull request to `defaultBranch` + * 2. return if exists pull request to othre branch + * 2. return None + */ + def getPullRequestFromBranch(userName: String, repositoryName: String, branch: String, defaultBranch: String) + (implicit s: Session): Option[(PullRequest, Issue)] = + PullRequests + .innerJoin(Issues).on { (t1, t2) => t1.byPrimaryKey(t2.userName, t2.repositoryName, t2.issueId) } + .filter { case (t1, t2) => + (t1.requestUserName === userName.bind) && + (t1.requestRepositoryName === repositoryName.bind) && + (t1.requestBranch === branch.bind) && + (t1.userName === userName.bind) && + (t1.repositoryName === repositoryName.bind) && + (t2.closed === false.bind) + } + .sortBy{ case (t1, t2) => t1.branch =!= defaultBranch.bind } + .firstOption + + /** * Fetch pull request contents into refs/pull/${issueId}/head and update pull request table. */ def updatePullRequests(owner: String, repository: String, branch: String)(implicit s: Session): Unit = diff --git a/src/main/twirl/gitbucket/core/repo/files.scala.html b/src/main/twirl/gitbucket/core/repo/files.scala.html index 11d5f70..4695c0e 100644 --- a/src/main/twirl/gitbucket/core/repo/files.scala.html +++ b/src/main/twirl/gitbucket/core/repo/files.scala.html @@ -6,6 +6,7 @@ files: List[gitbucket.core.util.JGitUtil.FileInfo], readme: Option[(List[String], String)], hasWritePermission: Boolean, + branchPullRequest: Option[(gitbucket.core.model.PullRequest, gitbucket.core.model.Issue)], info: Option[Any] = None, error: Option[Any] = None)(implicit context: gitbucket.core.controller.Context) @import context._ @@ -13,6 +14,11 @@ @html.main(s"${repository.owner}/${repository.name}", Some(repository)) { @html.menu("code", repository, Some(branch), pathList.isEmpty, groupNames.isEmpty, info, error){
+ @branchPullRequest.map{ case (pullRequest, issue) => + #@pullRequest.issueId + }.getOrElse{ + + } @helper.html.branchcontrol( branch, repository, diff --git a/src/main/webapp/assets/common/css/gitbucket.css b/src/main/webapp/assets/common/css/gitbucket.css index f365977..925897b 100644 --- a/src/main/webapp/assets/common/css/gitbucket.css +++ b/src/main/webapp/assets/common/css/gitbucket.css @@ -701,6 +701,12 @@ padding-left: 16px; } +.btn-pullrequest-branch{ + background: none; + border: 1px solid #0088cc; + color: #0088cc; +} + /****************************************************************************/ /* nav pulls group */ /****************************************************************************/ diff --git a/src/test/scala/gitbucket/core/service/PullRequestServiceSpec.scala b/src/test/scala/gitbucket/core/service/PullRequestServiceSpec.scala new file mode 100644 index 0000000..e5741de --- /dev/null +++ b/src/test/scala/gitbucket/core/service/PullRequestServiceSpec.scala @@ -0,0 +1,33 @@ +package gitbucket.core.service + +import gitbucket.core.model._ +import gitbucket.core.model.Profile._ + +import org.specs2.mutable.Specification + +class PullRequestServiceSpec extends Specification with ServiceSpecBase with PullRequestService with IssuesService { + def swap(r: (Issue, PullRequest)) = (r._2 -> r._1) + "PullRequestService.getPullRequestFromBranch" should { + """ + |return pull request if exists pull request from `branch` to `defaultBranch` and not closed. + |return pull request if exists pull request from `branch` to othre branch and not closed. + |return None if all pull request is closed""".stripMargin.trim in { withTestDB { implicit se => + generateNewUserWithDBRepository("user1", "repo1") + generateNewUserWithDBRepository("user1", "repo2") + generateNewUserWithDBRepository("user2", "repo1") + generateNewPullRequest("user1/repo1/master", "user1/repo1/head2") // not target branch + generateNewPullRequest("user1/repo1/head1", "user1/repo1/master") // not target branch ( swap from, to ) + generateNewPullRequest("user1/repo1/master", "user2/repo1/head1") // othre user + generateNewPullRequest("user1/repo1/master", "user1/repo2/head1") // othre repository + val r1 = swap(generateNewPullRequest("user1/repo1/master2", "user1/repo1/head1")) + val r2 = swap(generateNewPullRequest("user1/repo1/master", "user1/repo1/head1")) + val r3 = swap(generateNewPullRequest("user1/repo1/master4", "user1/repo1/head1")) + getPullRequestFromBranch("user1", "repo1", "head1", "master") must_== Some(r2) + updateClosed("user1", "repo1", r2._1.issueId, true) + getPullRequestFromBranch("user1", "repo1", "head1", "master").get must beOneOf(r1, r2) + updateClosed("user1", "repo1", r1._1.issueId, true) + updateClosed("user1", "repo1", r3._1.issueId, true) + getPullRequestFromBranch("user1", "repo1", "head1", "master") must beNone + } } + } +} \ No newline at end of file diff --git a/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala b/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala index 103372b..195f7be 100644 --- a/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala +++ b/src/test/scala/gitbucket/core/service/ServiceSpecBase.scala @@ -39,7 +39,7 @@ with CommitStatusService (){} def generateNewUserWithDBRepository(userName:String, repositoryName:String)(implicit s:Session):Account = { - val ac = generateNewAccount(userName) + val ac = AccountService.getAccountByUserName(userName).getOrElse(generateNewAccount(userName)) dummyService.createRepository(repositoryName, userName, None, false) ac }