Make patch from DiffEntry

This commit is contained in:
Naoki Takezoe
2017-09-05 11:26:55 +09:00
parent dafabb6278
commit ef16804b49
7 changed files with 46 additions and 42 deletions

View File

@@ -5,9 +5,6 @@ import gitbucket.core.util.JGitUtil.{CommitInfo, DiffInfo}
import gitbucket.core.util.RepositoryName
import org.eclipse.jgit.diff.DiffEntry.ChangeType
import ApiCommits._
import difflib.{Delta, DiffUtils}
import scala.collection.JavaConverters._
case class ApiCommits(
url: ApiPath,
@@ -65,35 +62,21 @@ object ApiCommits {
def apply(repositoryName: RepositoryName, commitInfo: CommitInfo, diffs: Seq[DiffInfo], author: Account, committer: Account,
commentCount: Int): ApiCommits = {
// Is there better way to get diff status?
val files = diffs.map { diff =>
var additions = 0
var deletions = 0
var changes = 0
diff.changeType match {
case ChangeType.ADD => {
additions = additions + diff.newContent.getOrElse("").replace("\r\n", "\n").split("\n").size
}
case ChangeType.MODIFY => {
val oldLines = diff.oldContent.getOrElse("").replace("\r\n", "\n").split("\n")
val newLines = diff.newContent.getOrElse("").replace("\r\n", "\n").split("\n")
val patch = DiffUtils.diff(oldLines.toList.asJava, newLines.toList.asJava)
patch.getDeltas.asScala.map { delta =>
additions = additions + delta.getRevised.getLines.size
deletions = deletions + delta.getOriginal.getLines.size
}
}
case ChangeType.DELETE => {
deletions = deletions + diff.oldContent.getOrElse("").replace("\r\n", "\n").split("\n").size
}
diff.patch.getOrElse("").split("\n").foreach { line =>
if(line.startsWith("+")) additions = additions + 1
if(line.startsWith("-")) deletions = deletions + 1
}
File(
filename = if(diff.changeType == ChangeType.DELETE){ diff.oldPath } else { diff.newPath },
additions = additions,
deletions = deletions,
changes = changes,
changes = additions + deletions,
status = diff.changeType match {
case ChangeType.ADD => "added"
case ChangeType.MODIFY => "modified"
@@ -111,7 +94,7 @@ object ApiCommits {
} else {
ApiPath(s"/${repositoryName.fullName}/blob/${commitInfo.id}/${diff.newPath}")
},
patch = "" // TODO
patch = diff.patch.getOrElse("")
)
}

View File

@@ -630,7 +630,9 @@ trait ApiControllerBase extends ControllerBase {
}) getOrElse NotFound()
})
/**
* https://developer.github.com/v3/repos/commits/#get-a-single-commit
*/
get("/api/v3/repos/:owner/:repo/commits/:sha")(referrersOnly { repository =>
val owner = repository.owner
val name = repository.name
@@ -646,7 +648,7 @@ trait ApiControllerBase extends ControllerBase {
JsonFormat(ApiCommits(
repositoryName = RepositoryName(repository),
commitInfo = commitInfo,
diffs = JGitUtil.getDiffs(git, commitInfo.parents.head, commitInfo.id, true),
diffs = JGitUtil.getDiffs(git, commitInfo.parents.head, commitInfo.id, false, true),
author = getAccount(commitInfo.authorName, commitInfo.authorEmailAddress),
committer = getAccount(commitInfo.committerName, commitInfo.committerEmailAddress),
commentCount = getCommitComment(repository.owner, repository.name, sha).size

View File

@@ -431,7 +431,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
try {
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
defining(JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))) { revCommit =>
JGitUtil.getDiffs(git, id) match {
JGitUtil.getDiffs(git, id, false) match {
case (diffs, oldCommitId) =>
html.commit(id, new JGitUtil.CommitInfo(revCommit),
JGitUtil.getBranchesOfCommit(git, revCommit.getName),

View File

@@ -76,7 +76,7 @@ trait WikiControllerBase extends ControllerBase {
val Array(from, to) = params("commitId").split("\\.\\.\\.")
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
html.compare(Some(pageName), from, to, JGitUtil.getDiffs(git, from, to, true).filter(_.newPath == pageName + ".md"), repository,
html.compare(Some(pageName), from, to, JGitUtil.getDiffs(git, from, to, true, false).filter(_.newPath == pageName + ".md"), repository,
isEditable(repository), flash.get("info"))
}
})
@@ -85,7 +85,7 @@ trait WikiControllerBase extends ControllerBase {
val Array(from, to) = params("commitId").split("\\.\\.\\.")
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
html.compare(None, from, to, JGitUtil.getDiffs(git, from, to, true), repository,
html.compare(None, from, to, JGitUtil.getDiffs(git, from, to, true, false), repository,
isEditable(repository), flash.get("info"))
}
})

View File

@@ -230,7 +230,7 @@ trait PullRequestService { self: IssuesService with CommitsService =>
helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
}
val diffs = JGitUtil.getDiffs(newGit, oldId.getName, newId.getName, true)
val diffs = JGitUtil.getDiffs(newGit, oldId.getName, newId.getName, true, false)
(commits, diffs)
}

View File

@@ -347,7 +347,7 @@ class WikiCommitHook(owner: String, repository: String, pusher: String, baseUrl:
diffs._1.collect { case diff if diff.newPath.toLowerCase.endsWith(".md") =>
val action = if(diff.changeType == ChangeType.ADD) "created" else "edited"
val fileName = diff.newPath
println(action + " - " + fileName + " - " + commit.id)
//println(action + " - " + fileName + " - " + commit.id)
(action, fileName, commit.id)
}
}

View File

@@ -1,5 +1,7 @@
package gitbucket.core.util
import java.io.ByteArrayOutputStream
import gitbucket.core.service.RepositoryService
import org.eclipse.jgit.api.Git
import Directory._
@@ -22,6 +24,7 @@ import java.util.function.Consumer
import org.cache2k.{Cache2kBuilder, CacheEntry}
import org.eclipse.jgit.api.errors.{InvalidRefNameException, JGitInternalException, NoHeadException, RefAlreadyExistsException}
import org.eclipse.jgit.diff.{DiffEntry, DiffFormatter}
import org.eclipse.jgit.dircache.DirCacheEntry
import org.slf4j.LoggerFactory
@@ -114,7 +117,8 @@ object JGitUtil {
newObjectId: Option[String],
oldMode: String,
newMode: String,
tooLarge: Boolean
tooLarge: Boolean,
patch: Option[String]
)
/**
@@ -515,9 +519,10 @@ object JGitUtil {
}
/**
* Returns the tuple of diff of the given commit and the previous commit id.
* Returns the tuple of diff of the given commit and parent commit ids.
* DiffInfos returned from this method don't include the patch property.
*/
def getDiffs(git: Git, id: String, fetchContent: Boolean = true): (List[DiffInfo], Option[String]) = {
def getDiffs(git: Git, id: String, fetchContent: Boolean): (List[DiffInfo], Option[String]) = {
@scala.annotation.tailrec
def getCommitLog(i: java.util.Iterator[RevCommit], logs: List[RevCommit]): List[RevCommit] =
i.hasNext match {
@@ -538,7 +543,7 @@ object JGitUtil {
} else {
commits(1)
}
(getDiffs(git, oldCommit.getName, id, fetchContent), Some(oldCommit.getName))
(getDiffs(git, oldCommit.getName, id, fetchContent, false), Some(oldCommit.getName))
} else {
// initial commit
@@ -551,7 +556,7 @@ object JGitUtil {
buffer.append((if(!fetchContent){
DiffInfo(
changeType = ChangeType.ADD,
oldPath = null,
oldPath = "",
newPath = treeWalk.getPathString,
oldContent = None,
newContent = None,
@@ -561,12 +566,13 @@ object JGitUtil {
newObjectId = Option(treeWalk.getObjectId(0)).map(_.name),
oldMode = treeWalk.getFileMode(0).toString,
newMode = treeWalk.getFileMode(0).toString,
tooLarge = false
tooLarge = false,
patch = None
)
} else {
DiffInfo(
changeType = ChangeType.ADD,
oldPath = null,
oldPath = "",
newPath = treeWalk.getPathString,
oldContent = None,
newContent = JGitUtil.getContentFromId(git, treeWalk.getObjectId(0), false).filter(FileUtil.isText).map(convertFromByteArray),
@@ -576,7 +582,8 @@ object JGitUtil {
newObjectId = Option(treeWalk.getObjectId(0)).map(_.name),
oldMode = treeWalk.getFileMode(0).toString,
newMode = treeWalk.getFileMode(0).toString,
tooLarge = false
tooLarge = false,
patch = None
)
}))
}
@@ -586,7 +593,7 @@ object JGitUtil {
}
}
def getDiffs(git: Git, from: String, to: String, fetchContent: Boolean): List[DiffInfo] = {
def getDiffs(git: Git, from: String, to: String, fetchContent: Boolean, makePatch: Boolean): List[DiffInfo] = {
val reader = git.getRepository.newObjectReader
val oldTreeIter = new CanonicalTreeParser
oldTreeIter.reset(reader, git.getRepository.resolve(from + "^{tree}"))
@@ -612,7 +619,8 @@ object JGitUtil {
newObjectId = Option(diff.getNewId).map(_.name),
oldMode = diff.getOldMode.toString,
newMode = diff.getNewMode.toString,
tooLarge = true
tooLarge = true,
patch = None
)
} else {
val oldIsImage = FileUtil.isImage(diff.getOldPath)
@@ -630,7 +638,8 @@ object JGitUtil {
newObjectId = Option(diff.getNewId).map(_.name),
oldMode = diff.getOldMode.toString,
newMode = diff.getNewMode.toString,
tooLarge = false
tooLarge = false,
patch = (if(makePatch) Some(makePatchFromDiffEntry(git, diff)) else None)
)
} else {
DiffInfo(
@@ -645,13 +654,23 @@ object JGitUtil {
newObjectId = Option(diff.getNewId).map(_.name),
oldMode = diff.getOldMode.toString,
newMode = diff.getNewMode.toString,
tooLarge = false
tooLarge = false,
patch = (if(makePatch) Some(makePatchFromDiffEntry(git, diff)) else None)
)
}
}
}.toList
}
private def makePatchFromDiffEntry(git: Git, diff: DiffEntry): String = {
val out = new ByteArrayOutputStream()
using(new DiffFormatter(out)){ formatter =>
formatter.setRepository(git.getRepository)
formatter.format(diff)
val patch = new String(out.toByteArray)
patch.split("\n").drop(4).mkString("\n")
}
}
/**
* Returns the list of branch names of the specified commit.