diff --git a/src/main/scala/app/PullRequestsController.scala b/src/main/scala/app/PullRequestsController.scala index 0d42d92..8219b9c 100644 --- a/src/main/scala/app/PullRequestsController.scala +++ b/src/main/scala/app/PullRequestsController.scala @@ -76,19 +76,24 @@ getMilestonesWithIssueCount(owner, name), commits, diffs, - if(issue.closed){ - false - } else { - checkConflict(owner, name, pullreq.branch, owner, name, pullreq.requestBranch) - }, hasWritePermission(owner, name, context.loginAccount), - repository, - s"${baseUrl}${context.path}/git/${pullreq.requestUserName}/${pullreq.requestRepositoryName}.git") + repository) } } getOrElse NotFound } }) + ajaxGet("/:owner/:repository/pull/:id/mergeguide")(collaboratorsOnly { repository => + defining(repository.owner, repository.name, params("id").toInt){ case (owner, name, issueId) => + getPullRequest(owner, name, issueId) map { case(issue, pullreq) => + pulls.html.mergeguide( + checkConflict(owner, name, pullreq.branch, owner, name, pullreq.requestBranch), + pullreq, + s"${baseUrl}${context.path}/git/${pullreq.requestUserName}/${pullreq.requestRepositoryName}.git") + } getOrElse NotFound() + } + }) + post("/:owner/:repository/pull/:id/merge", mergeForm)(collaboratorsOnly { (form, repository) => defining(repository.owner, repository.name, params("id").toInt){ case (owner, name, issueId) => LockUtil.lock(s"${owner}/${name}/merge"){ @@ -164,41 +169,6 @@ } }) - /** - * Checks whether conflict will be caused in merging. - * Returns true if conflict will be caused. - */ - private def checkConflict(userName: String, repositoryName: String, branch: String, - requestUserName: String, requestRepositoryName: String, requestBranch: String): Boolean = { - // TODO Are there more quick way? - LockUtil.lock(s"${userName}/${repositoryName}/merge-check"){ - val remote = getRepositoryDir(userName, repositoryName) - val tmpdir = new java.io.File(getTemporaryDir(userName, repositoryName), "merge-check") - if(tmpdir.exists()){ - FileUtils.deleteDirectory(tmpdir) - } - - val git = Git.cloneRepository.setDirectory(tmpdir).setURI(remote.toURI.toString).setBranch(branch).call - try { - git.checkout.setName(branch).call - - git.fetch - .setRemote(getRepositoryDir(requestUserName, requestRepositoryName).toURI.toString) - .setRefSpecs(new RefSpec(s"refs/heads/${branch}:refs/heads/${requestBranch}")).call - - val result = git.merge - .include(git.getRepository.resolve("FETCH_HEAD")) - .setCommit(false).call - - result.getConflicts != null - - } finally { - git.getRepository.close - FileUtils.deleteDirectory(tmpdir) - } - } - } - get("/:owner/:repository/compare")(referrersOnly { forkedRepository => (forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match { case (Some(originUserName), Some(originRepositoryName)) => { @@ -229,11 +199,11 @@ val (forkedOwner, tmpForkedBranch) = parseCompareIdentifie(forked, repository.owner) (getRepository(originOwner, repository.name, baseUrl), - getRepository(forkedOwner, repository.name, baseUrl)) match { + getRepository(forkedOwner, repository.name, baseUrl)) match { case (Some(originRepository), Some(forkedRepository)) => { using( Git.open(getRepositoryDir(originOwner, repository.name)), - Git.open(getRepositoryDir(forkedOwner, repository.name)) + Git.open(getRepositoryDir(forkedOwner, repository.name)) ){ case (oldGit, newGit) => val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2 val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2 @@ -259,7 +229,6 @@ forkedBranch, oldId.getName, newId.getName, - checkConflict(originOwner, repository.name, originBranch, forkedOwner, repository.name, forkedBranch), repository, originRepository, forkedRepository, @@ -270,6 +239,29 @@ } }) + ajaxGet("/:owner/:repository/compare/*...*/mergecheck")(collaboratorsOnly { repository => + val Seq(origin, forked) = multiParams("splat") + val (originOwner, tmpOriginBranch) = parseCompareIdentifie(origin, repository.owner) + val (forkedOwner, tmpForkedBranch) = parseCompareIdentifie(forked, repository.owner) + + (getRepository(originOwner, repository.name, baseUrl), + getRepository(forkedOwner, repository.name, baseUrl)) match { + case (Some(originRepository), Some(forkedRepository)) => { + using( + Git.open(getRepositoryDir(originOwner, repository.name)), + Git.open(getRepositoryDir(forkedOwner, repository.name)) + ){ case (oldGit, newGit) => + val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2 + val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2 + + pulls.html.mergecheck( + checkConflict(originOwner, repository.name, originBranch, forkedOwner, repository.name, forkedBranch)) + } + } + case _ => NotFound() + } + }) + post("/:owner/:repository/pulls/new", pullRequestForm)(referrersOnly { (form, repository) => val loginUserName = context.loginAccount.get.userName @@ -314,6 +306,40 @@ }) /** + * Checks whether conflict will be caused in merging. Returns true if conflict will be caused. + */ + private def checkConflict(userName: String, repositoryName: String, branch: String, + requestUserName: String, requestRepositoryName: String, requestBranch: String): Boolean = { + // TODO Are there more quick way? + LockUtil.lock(s"${userName}/${repositoryName}/merge-check"){ + val remote = getRepositoryDir(userName, repositoryName) + val tmpdir = new java.io.File(getTemporaryDir(userName, repositoryName), "merge-check") + if(tmpdir.exists()){ + FileUtils.deleteDirectory(tmpdir) + } + + val git = Git.cloneRepository.setDirectory(tmpdir).setURI(remote.toURI.toString).setBranch(branch).call + try { + git.checkout.setName(branch).call + + git.fetch + .setRemote(getRepositoryDir(requestUserName, requestRepositoryName).toURI.toString) + .setRefSpecs(new RefSpec(s"refs/heads/${branch}:refs/heads/${requestBranch}")).call + + val result = git.merge + .include(git.getRepository.resolve("FETCH_HEAD")) + .setCommit(false).call + + result.getConflicts != null + + } finally { + git.getRepository.close + FileUtils.deleteDirectory(tmpdir) + } + } + } + + /** * Parses branch identifier and extracts owner and branch name as tuple. * * - "owner:branch" to ("owner", "branch") @@ -382,7 +408,7 @@ getPullRequestCountGroupByUser(condition.state == "closed", owner, Some(repoName)), userName, page, - countIssue(condition.copy(state = "open"), filterUser, true, owner -> repoName), + countIssue(condition.copy(state = "open" ), filterUser, true, owner -> repoName), countIssue(condition.copy(state = "closed"), filterUser, true, owner -> repoName), countIssue(condition, Map.empty, true, owner -> repoName), condition, diff --git a/src/main/twirl/pulls/compare.scala.html b/src/main/twirl/pulls/compare.scala.html index d523d2d..3c893a2 100644 --- a/src/main/twirl/pulls/compare.scala.html +++ b/src/main/twirl/pulls/compare.scala.html @@ -5,7 +5,6 @@ forkedId: String, sourceId: String, commitId: String, - hasConflict: Boolean, repository: service.RepositoryService.RepositoryInfo, originRepository: service.RepositoryService.RepositoryInfo, forkedRepository: service.RepositoryService.RepositoryInfo, @@ -52,14 +51,9 @@