Format code

This commit is contained in:
Naoki Takezoe
2017-12-10 17:39:45 +09:00
parent 2d58b7f2d7
commit a03d1c97c2
2 changed files with 47 additions and 26 deletions

View File

@@ -3,25 +3,26 @@ package gitbucket.core.service
import gitbucket.core.model.Account import gitbucket.core.model.Account
import gitbucket.core.util.Directory._ import gitbucket.core.util.Directory._
import gitbucket.core.util.SyntaxSugars._ import gitbucket.core.util.SyntaxSugars._
import org.eclipse.jgit.merge.MergeStrategy import org.eclipse.jgit.merge.MergeStrategy
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
import org.eclipse.jgit.transport.RefSpec import org.eclipse.jgit.transport.RefSpec
import org.eclipse.jgit.errors.NoMergeBaseException import org.eclipse.jgit.errors.NoMergeBaseException
import org.eclipse.jgit.lib.{ObjectId, CommitBuilder, PersonIdent, Repository} import org.eclipse.jgit.lib.{CommitBuilder, ObjectId, PersonIdent, Repository}
import org.eclipse.jgit.revwalk.RevWalk import org.eclipse.jgit.revwalk.{RevCommit, RevWalk}
trait MergeService { trait MergeService {
import MergeService._ import MergeService._
/** /**
* Checks whether conflict will be caused in merging within pull request. * Checks whether conflict will be caused in merging within pull request.
* Returns true if conflict will be caused. * Returns true if conflict will be caused.
*/ */
def checkConflict(userName: String, repositoryName: String, branch: String, issueId: Int): Boolean = { def checkConflict(userName: String, repositoryName: String, branch: String, issueId: Int): Boolean = {
using(Git.open(getRepositoryDir(userName, repositoryName))) { git => using(Git.open(getRepositoryDir(userName, repositoryName))) { git =>
MergeCacheInfo(git, branch, issueId).checkConflict() new MergeCacheInfo(git, branch, issueId).checkConflict()
} }
} }
/** /**
* Checks whether conflict will be caused in merging within pull request. * Checks whether conflict will be caused in merging within pull request.
* only cache check. * only cache check.
@@ -30,13 +31,15 @@ trait MergeService {
*/ */
def checkConflictCache(userName: String, repositoryName: String, branch: String, issueId: Int): Option[Boolean] = { def checkConflictCache(userName: String, repositoryName: String, branch: String, issueId: Int): Option[Boolean] = {
using(Git.open(getRepositoryDir(userName, repositoryName))) { git => using(Git.open(getRepositoryDir(userName, repositoryName))) { git =>
MergeCacheInfo(git, branch, issueId).checkConflictCache() new MergeCacheInfo(git, branch, issueId).checkConflictCache()
} }
} }
/** merge pull request */ /** merge pull request */
def mergePullRequest(git:Git, branch: String, issueId: Int, message:String, committer: PersonIdent): Unit = { def mergePullRequest(git:Git, branch: String, issueId: Int, message:String, committer: PersonIdent): Unit = {
MergeCacheInfo(git, branch, issueId).merge(message, committer) new MergeCacheInfo(git, branch, issueId).merge(message, committer)
} }
/** fetch remote branch to my repository refs/pull/{issueId}/head */ /** fetch remote branch to my repository refs/pull/{issueId}/head */
def fetchAsPullRequest(userName: String, repositoryName: String, requestUserName: String, requestRepositoryName: String, requestBranch:String, issueId:Int){ def fetchAsPullRequest(userName: String, repositoryName: String, requestUserName: String, requestRepositoryName: String, requestBranch:String, issueId:Int){
using(Git.open(getRepositoryDir(userName, repositoryName))){ git => using(Git.open(getRepositoryDir(userName, repositoryName))){ git =>
@@ -46,6 +49,7 @@ trait MergeService {
.call .call
} }
} }
/** /**
* Checks whether conflict will be caused in merging. Returns true if conflict will be caused. * Checks whether conflict will be caused in merging. Returns true if conflict will be caused.
*/ */
@@ -81,6 +85,7 @@ trait MergeService {
} }
} }
} }
/** /**
* Checks whether conflict will be caused in merging. Returns true if conflict will be caused. * Checks whether conflict will be caused in merging. Returns true if conflict will be caused.
*/ */
@@ -102,7 +107,9 @@ trait MergeService {
} }
} }
object MergeService{ object MergeService{
object Util{ object Util{
// return treeId // return treeId
def createMergeCommit(repository: Repository, treeId: ObjectId, committer: PersonIdent, message: String, parents: Seq[ObjectId]): ObjectId = { def createMergeCommit(repository: Repository, treeId: ObjectId, committer: PersonIdent, message: String, parents: Seq[ObjectId]): ObjectId = {
@@ -119,6 +126,7 @@ object MergeService{
inserter.close() inserter.close()
mergeCommitId mergeCommitId
} }
def updateRefs(repository: Repository, ref: String, newObjectId: ObjectId, force: Boolean, committer: PersonIdent, refLogMessage: Option[String] = None): Unit = { def updateRefs(repository: Repository, ref: String, newObjectId: ObjectId, force: Boolean, committer: PersonIdent, refLogMessage: Option[String] = None): Unit = {
// update refs // update refs
val refUpdate = repository.updateRef(ref) val refUpdate = repository.updateRef(ref)
@@ -129,12 +137,16 @@ object MergeService{
refUpdate.update() refUpdate.update()
} }
} }
case class MergeCacheInfo(git:Git, branch:String, issueId:Int){
val repository = git.getRepository class MergeCacheInfo(git: Git, branch: String, issueId: Int){
val mergedBranchName = s"refs/pull/${issueId}/merge"
val conflictedBranchName = s"refs/pull/${issueId}/conflict" private val repository = git.getRepository
private val mergedBranchName = s"refs/pull/${issueId}/merge"
private val conflictedBranchName = s"refs/pull/${issueId}/conflict"
lazy val mergeBaseTip = repository.resolve(s"refs/heads/${branch}") lazy val mergeBaseTip = repository.resolve(s"refs/heads/${branch}")
lazy val mergeTip = repository.resolve(s"refs/pull/${issueId}/head") lazy val mergeTip = repository.resolve(s"refs/pull/${issueId}/head")
def checkConflictCache(): Option[Boolean] = { def checkConflictCache(): Option[Boolean] = {
Option(repository.resolve(mergedBranchName)).flatMap { merged => Option(repository.resolve(mergedBranchName)).flatMap { merged =>
if(parseCommit(merged).getParents().toSet == Set( mergeBaseTip, mergeTip )){ if(parseCommit(merged).getParents().toSet == Set( mergeBaseTip, mergeTip )){
@@ -152,9 +164,11 @@ object MergeService{
} }
}) })
} }
def checkConflict(): Boolean = { def checkConflict(): Boolean = {
checkConflictCache.getOrElse(checkConflictForce) checkConflictCache.getOrElse(checkConflictForce)
} }
def checkConflictForce(): Boolean = { def checkConflictForce(): Boolean = {
val merger = MergeStrategy.RECURSIVE.newMerger(repository, true) val merger = MergeStrategy.RECURSIVE.newMerger(repository, true)
val conflicted = try { val conflicted = try {
@@ -164,11 +178,13 @@ object MergeService{
} }
val mergeTipCommit = using(new RevWalk( repository ))(_.parseCommit( mergeTip )) val mergeTipCommit = using(new RevWalk( repository ))(_.parseCommit( mergeTip ))
val committer = mergeTipCommit.getCommitterIdent val committer = mergeTipCommit.getCommitterIdent
def updateBranch(treeId: ObjectId, message: String, branchName: String){ def updateBranch(treeId: ObjectId, message: String, branchName: String){
// creates merge commit // creates merge commit
val mergeCommitId = createMergeCommit(treeId, committer, message) val mergeCommitId = createMergeCommit(treeId, committer, message)
Util.updateRefs(repository, branchName, mergeCommitId, true, committer) Util.updateRefs(repository, branchName, mergeCommitId, true, committer)
} }
if(!conflicted){ if(!conflicted){
updateBranch(merger.getResultTreeId, s"Merge ${mergeTip.name} into ${mergeBaseTip.name}", mergedBranchName) updateBranch(merger.getResultTreeId, s"Merge ${mergeTip.name} into ${mergeBaseTip.name}", mergedBranchName)
git.branchDelete().setForce(true).setBranchNames(conflictedBranchName).call() git.branchDelete().setForce(true).setBranchNames(conflictedBranchName).call()
@@ -178,21 +194,26 @@ object MergeService{
} }
conflicted conflicted
} }
// update branch from cache // update branch from cache
def merge(message: String, committer: PersonIdent) = { def merge(message: String, committer: PersonIdent) = {
if(checkConflict()){ if(checkConflict()){
throw new RuntimeException("This pull request can't merge automatically.") throw new RuntimeException("This pull request can't merge automatically.")
} }
val mergeResultCommit = parseCommit( Option(repository.resolve(mergedBranchName)).getOrElse(throw new RuntimeException(s"not found branch ${mergedBranchName}")) ) val mergeResultCommit = parseCommit(Option(repository.resolve(mergedBranchName)).getOrElse {
throw new RuntimeException(s"not found branch ${mergedBranchName}")
})
// creates merge commit // creates merge commit
val mergeCommitId = createMergeCommit(mergeResultCommit.getTree().getId(), committer, message) val mergeCommitId = createMergeCommit(mergeResultCommit.getTree().getId(), committer, message)
// update refs // update refs
Util.updateRefs(repository, s"refs/heads/${branch}", mergeCommitId, false, committer, Some("merged")) Util.updateRefs(repository, s"refs/heads/${branch}", mergeCommitId, false, committer, Some("merged"))
} }
// return treeId // return treeId
private def createMergeCommit(treeId: ObjectId, committer: PersonIdent, message: String) = private def createMergeCommit(treeId: ObjectId, committer: PersonIdent, message: String) =
Util.createMergeCommit(repository, treeId, committer, message, Seq[ObjectId](mergeBaseTip, mergeTip)) Util.createMergeCommit(repository, treeId, committer, message, Seq[ObjectId](mergeBaseTip, mergeTip))
private def parseCommit(id:ObjectId) = using(new RevWalk( repository ))(_.parseCommit(id)) private def parseCommit(id:ObjectId) = using(new RevWalk( repository ))(_.parseCommit(id))
} }
} }