Fix rebase process

This commit is contained in:
Naoki Takezoe
2017-12-11 20:08:03 +09:00
parent eb61bc50d6
commit 0309496df6
2 changed files with 48 additions and 17 deletions

View File

@@ -16,6 +16,7 @@ import gitbucket.core.util._
import org.scalatra.forms._ import org.scalatra.forms._
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.PersonIdent import org.eclipse.jgit.lib.PersonIdent
import org.eclipse.jgit.revwalk.RevWalk
import scala.collection.JavaConverters._ import scala.collection.JavaConverters._
@@ -259,25 +260,30 @@ trait PullRequestsControllerBase extends ControllerBase {
// record activity // record activity
recordMergeActivity(owner, name, loginAccount.userName, issueId, form.message) recordMergeActivity(owner, name, loginAccount.userName, issueId, form.message)
val (commits, _) = getRequestCompareInfo(owner, name, pullreq.commitIdFrom,
pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo)
val revCommits = using(new RevWalk( git.getRepository )){ revWalk =>
commits.flatten.map { commit =>
revWalk.parseCommit(git.getRepository.resolve(commit.id))
}
}.reverse
// merge git repository // merge git repository
println(form.strategy)
form.strategy match { form.strategy match {
case "merge-commit" => case "merge-commit" =>
mergePullRequest(git, pullreq.branch, issueId, mergePullRequest(git, pullreq.branch, issueId,
s"Merge pull request #${issueId} from ${pullreq.requestUserName}/${pullreq.requestBranch}\n\n" + form.message, s"Merge pull request #${issueId} from ${pullreq.requestUserName}/${pullreq.requestBranch}\n\n" + form.message,
new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)) new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
case "rebase" => case "rebase" =>
rebasePullRequest(git, pullreq.branch, issueId, rebasePullRequest(git, pullreq.branch, issueId, revCommits,
new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)) new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
case "squash" => case "squash" =>
squashPullRequest(git, pullreq.branch, issueId, squashPullRequest(git, pullreq.branch, issueId,
s"Merge pull request #${issueId} from ${pullreq.requestUserName}/${pullreq.requestBranch}\n\n" + form.message, s"${issue.title} (#${issueId})\n\n" + form.message,
new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)) new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
} }
val (commits, _) = getRequestCompareInfo(owner, name, pullreq.commitIdFrom,
pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo)
// close issue by content of pull request // close issue by content of pull request
val defaultBranch = getRepository(owner, name).get.repository.defaultBranch val defaultBranch = getRepository(owner, name).get.repository.defaultBranch
if(pullreq.branch == defaultBranch){ if(pullreq.branch == defaultBranch){

View File

@@ -8,7 +8,7 @@ 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.{CommitBuilder, ObjectId, 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._
@@ -40,11 +40,12 @@ trait MergeService {
new MergeCacheInfo(git, branch, issueId).merge(message, committer) new MergeCacheInfo(git, branch, issueId).merge(message, committer)
} }
/** rebase to the pull request branch */ /** rebase to the head of the pull request branch */
def rebasePullRequest(git: Git, branch: String, issueId: Int, committer: PersonIdent): Unit = { def rebasePullRequest(git: Git, branch: String, issueId: Int, commits: Seq[RevCommit], committer: PersonIdent): Unit = {
new MergeCacheInfo(git, branch, issueId).rebase(committer) new MergeCacheInfo(git, branch, issueId).rebase(committer, commits)
} }
/** squash commits in the pull request and append it */
def squashPullRequest(git: Git, branch: String, issueId: Int, message: String, committer: PersonIdent): Unit = { def squashPullRequest(git: Git, branch: String, issueId: Int, message: String, committer: PersonIdent): Unit = {
new MergeCacheInfo(git, branch, issueId).squash(message, committer) new MergeCacheInfo(git, branch, issueId).squash(message, committer)
} }
@@ -205,7 +206,6 @@ object MergeService{
conflicted conflicted
} }
// update branch from cache
def merge(message: String, committer: PersonIdent): Unit = { def merge(message: String, committer: PersonIdent): Unit = {
if(checkConflict()){ if(checkConflict()){
throw new RuntimeException("This pull request can't merge automatically.") throw new RuntimeException("This pull request can't merge automatically.")
@@ -219,12 +219,37 @@ object MergeService{
Util.updateRefs(repository, s"refs/heads/${branch}", mergeCommitId, false, committer, Some("merged")) // TODO reflog message Util.updateRefs(repository, s"refs/heads/${branch}", mergeCommitId, false, committer, Some("merged")) // TODO reflog message
} }
def rebase(committer: PersonIdent): Unit = { def rebase(committer: PersonIdent, commits: Seq[RevCommit]): Unit = {
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 mergeTipCommit = using(new RevWalk( repository ))(_.parseCommit( mergeTip ))
Util.updateRefs(repository, s"refs/heads/${branch}", mergeTipCommit.getId, false, committer, Some("merged")) // TODO reflog message def _cloneCommit(commit: RevCommit, parents: Array[ObjectId]): CommitBuilder = {
val newCommit = new CommitBuilder()
newCommit.setTreeId(commit.getTree.getId)
parents.foreach { parentId =>
newCommit.addParentId(parentId)
}
newCommit.setAuthor(commit.getAuthorIdent)
newCommit.setCommitter(committer)
newCommit.setMessage(commit.getFullMessage)
newCommit
}
val mergeBaseTipCommit = using(new RevWalk( repository ))(_.parseCommit( mergeBaseTip ))
var previousId = mergeBaseTipCommit.getId
val inserter = repository.newObjectInserter
commits.foreach { commit =>
val nextCommit = _cloneCommit(commit, Array(previousId))
previousId = inserter.insert(nextCommit)
}
inserter.flush()
inserter.close()
Util.updateRefs(repository, s"refs/heads/${branch}", previousId, false, committer, Some("merged")) // TODO reflog message
} }
def squash(message: String, committer: PersonIdent): Unit = { def squash(message: String, committer: PersonIdent): Unit = {
@@ -232,13 +257,13 @@ object MergeService{
throw new RuntimeException("This pull request can't merge automatically.") throw new RuntimeException("This pull request can't merge automatically.")
} }
val baseCommit = using(new RevWalk( repository ))(_.parseCommit(mergeBaseTip)) val mergeBaseTipCommit = using(new RevWalk( repository ))(_.parseCommit(mergeBaseTip))
val mergeBranchHeadCommit = using(new RevWalk( repository ))(_.parseCommit(repository.resolve(mergedBranchName))) val mergeBranchHeadCommit = using(new RevWalk( repository ))(_.parseCommit(repository.resolve(mergedBranchName)))
// Create squash commit // Create squash commit
val mergeCommit = new CommitBuilder() val mergeCommit = new CommitBuilder()
mergeCommit.setTreeId(mergeBranchHeadCommit.getTree.getId) mergeCommit.setTreeId(mergeBranchHeadCommit.getTree.getId)
mergeCommit.setParentId(baseCommit) mergeCommit.setParentId(mergeBaseTipCommit)
mergeCommit.setAuthor(mergeBranchHeadCommit.getAuthorIdent) mergeCommit.setAuthor(mergeBranchHeadCommit.getAuthorIdent)
mergeCommit.setCommitter(committer) mergeCommit.setCommitter(committer)
mergeCommit.setMessage(message) mergeCommit.setMessage(message)
@@ -259,7 +284,7 @@ object MergeService{
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))
} }
} }