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 gitbucket.core.util.RepositoryName
import org.eclipse.jgit.diff.DiffEntry.ChangeType import org.eclipse.jgit.diff.DiffEntry.ChangeType
import ApiCommits._ import ApiCommits._
import difflib.{Delta, DiffUtils}
import scala.collection.JavaConverters._
case class ApiCommits( case class ApiCommits(
url: ApiPath, url: ApiPath,
@@ -65,35 +62,21 @@ object ApiCommits {
def apply(repositoryName: RepositoryName, commitInfo: CommitInfo, diffs: Seq[DiffInfo], author: Account, committer: Account, def apply(repositoryName: RepositoryName, commitInfo: CommitInfo, diffs: Seq[DiffInfo], author: Account, committer: Account,
commentCount: Int): ApiCommits = { commentCount: Int): ApiCommits = {
// Is there better way to get diff status?
val files = diffs.map { diff => val files = diffs.map { diff =>
var additions = 0 var additions = 0
var deletions = 0 var deletions = 0
var changes = 0
diff.changeType match { diff.patch.getOrElse("").split("\n").foreach { line =>
case ChangeType.ADD => { if(line.startsWith("+")) additions = additions + 1
additions = additions + diff.newContent.getOrElse("").replace("\r\n", "\n").split("\n").size if(line.startsWith("-")) deletions = deletions + 1
}
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
}
} }
File( File(
filename = if(diff.changeType == ChangeType.DELETE){ diff.oldPath } else { diff.newPath }, filename = if(diff.changeType == ChangeType.DELETE){ diff.oldPath } else { diff.newPath },
additions = additions, additions = additions,
deletions = deletions, deletions = deletions,
changes = changes, changes = additions + deletions,
status = diff.changeType match { status = diff.changeType match {
case ChangeType.ADD => "added" case ChangeType.ADD => "added"
case ChangeType.MODIFY => "modified" case ChangeType.MODIFY => "modified"
@@ -111,7 +94,7 @@ object ApiCommits {
} else { } else {
ApiPath(s"/${repositoryName.fullName}/blob/${commitInfo.id}/${diff.newPath}") 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() }) getOrElse NotFound()
}) })
/**
* https://developer.github.com/v3/repos/commits/#get-a-single-commit
*/
get("/api/v3/repos/:owner/:repo/commits/:sha")(referrersOnly { repository => get("/api/v3/repos/:owner/:repo/commits/:sha")(referrersOnly { repository =>
val owner = repository.owner val owner = repository.owner
val name = repository.name val name = repository.name
@@ -646,7 +648,7 @@ trait ApiControllerBase extends ControllerBase {
JsonFormat(ApiCommits( JsonFormat(ApiCommits(
repositoryName = RepositoryName(repository), repositoryName = RepositoryName(repository),
commitInfo = commitInfo, 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), author = getAccount(commitInfo.authorName, commitInfo.authorEmailAddress),
committer = getAccount(commitInfo.committerName, commitInfo.committerEmailAddress), committer = getAccount(commitInfo.committerName, commitInfo.committerEmailAddress),
commentCount = getCommitComment(repository.owner, repository.name, sha).size commentCount = getCommitComment(repository.owner, repository.name, sha).size

View File

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

View File

@@ -76,7 +76,7 @@ trait WikiControllerBase extends ControllerBase {
val Array(from, to) = params("commitId").split("\\.\\.\\.") val Array(from, to) = params("commitId").split("\\.\\.\\.")
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git => 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")) isEditable(repository), flash.get("info"))
} }
}) })
@@ -85,7 +85,7 @@ trait WikiControllerBase extends ControllerBase {
val Array(from, to) = params("commitId").split("\\.\\.\\.") val Array(from, to) = params("commitId").split("\\.\\.\\.")
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git => 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")) 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) 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) (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") => diffs._1.collect { case diff if diff.newPath.toLowerCase.endsWith(".md") =>
val action = if(diff.changeType == ChangeType.ADD) "created" else "edited" val action = if(diff.changeType == ChangeType.ADD) "created" else "edited"
val fileName = diff.newPath val fileName = diff.newPath
println(action + " - " + fileName + " - " + commit.id) //println(action + " - " + fileName + " - " + commit.id)
(action, fileName, commit.id) (action, fileName, commit.id)
} }
} }

View File

@@ -1,5 +1,7 @@
package gitbucket.core.util package gitbucket.core.util
import java.io.ByteArrayOutputStream
import gitbucket.core.service.RepositoryService import gitbucket.core.service.RepositoryService
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
import Directory._ import Directory._
@@ -22,6 +24,7 @@ import java.util.function.Consumer
import org.cache2k.{Cache2kBuilder, CacheEntry} import org.cache2k.{Cache2kBuilder, CacheEntry}
import org.eclipse.jgit.api.errors.{InvalidRefNameException, JGitInternalException, NoHeadException, RefAlreadyExistsException} 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.eclipse.jgit.dircache.DirCacheEntry
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@@ -114,7 +117,8 @@ object JGitUtil {
newObjectId: Option[String], newObjectId: Option[String],
oldMode: String, oldMode: String,
newMode: 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 @scala.annotation.tailrec
def getCommitLog(i: java.util.Iterator[RevCommit], logs: List[RevCommit]): List[RevCommit] = def getCommitLog(i: java.util.Iterator[RevCommit], logs: List[RevCommit]): List[RevCommit] =
i.hasNext match { i.hasNext match {
@@ -538,7 +543,7 @@ object JGitUtil {
} else { } else {
commits(1) commits(1)
} }
(getDiffs(git, oldCommit.getName, id, fetchContent), Some(oldCommit.getName)) (getDiffs(git, oldCommit.getName, id, fetchContent, false), Some(oldCommit.getName))
} else { } else {
// initial commit // initial commit
@@ -551,7 +556,7 @@ object JGitUtil {
buffer.append((if(!fetchContent){ buffer.append((if(!fetchContent){
DiffInfo( DiffInfo(
changeType = ChangeType.ADD, changeType = ChangeType.ADD,
oldPath = null, oldPath = "",
newPath = treeWalk.getPathString, newPath = treeWalk.getPathString,
oldContent = None, oldContent = None,
newContent = None, newContent = None,
@@ -561,12 +566,13 @@ object JGitUtil {
newObjectId = Option(treeWalk.getObjectId(0)).map(_.name), newObjectId = Option(treeWalk.getObjectId(0)).map(_.name),
oldMode = treeWalk.getFileMode(0).toString, oldMode = treeWalk.getFileMode(0).toString,
newMode = treeWalk.getFileMode(0).toString, newMode = treeWalk.getFileMode(0).toString,
tooLarge = false tooLarge = false,
patch = None
) )
} else { } else {
DiffInfo( DiffInfo(
changeType = ChangeType.ADD, changeType = ChangeType.ADD,
oldPath = null, oldPath = "",
newPath = treeWalk.getPathString, newPath = treeWalk.getPathString,
oldContent = None, oldContent = None,
newContent = JGitUtil.getContentFromId(git, treeWalk.getObjectId(0), false).filter(FileUtil.isText).map(convertFromByteArray), 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), newObjectId = Option(treeWalk.getObjectId(0)).map(_.name),
oldMode = treeWalk.getFileMode(0).toString, oldMode = treeWalk.getFileMode(0).toString,
newMode = 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 reader = git.getRepository.newObjectReader
val oldTreeIter = new CanonicalTreeParser val oldTreeIter = new CanonicalTreeParser
oldTreeIter.reset(reader, git.getRepository.resolve(from + "^{tree}")) oldTreeIter.reset(reader, git.getRepository.resolve(from + "^{tree}"))
@@ -612,7 +619,8 @@ object JGitUtil {
newObjectId = Option(diff.getNewId).map(_.name), newObjectId = Option(diff.getNewId).map(_.name),
oldMode = diff.getOldMode.toString, oldMode = diff.getOldMode.toString,
newMode = diff.getNewMode.toString, newMode = diff.getNewMode.toString,
tooLarge = true tooLarge = true,
patch = None
) )
} else { } else {
val oldIsImage = FileUtil.isImage(diff.getOldPath) val oldIsImage = FileUtil.isImage(diff.getOldPath)
@@ -630,7 +638,8 @@ object JGitUtil {
newObjectId = Option(diff.getNewId).map(_.name), newObjectId = Option(diff.getNewId).map(_.name),
oldMode = diff.getOldMode.toString, oldMode = diff.getOldMode.toString,
newMode = diff.getNewMode.toString, newMode = diff.getNewMode.toString,
tooLarge = false tooLarge = false,
patch = (if(makePatch) Some(makePatchFromDiffEntry(git, diff)) else None)
) )
} else { } else {
DiffInfo( DiffInfo(
@@ -645,13 +654,23 @@ object JGitUtil {
newObjectId = Option(diff.getNewId).map(_.name), newObjectId = Option(diff.getNewId).map(_.name),
oldMode = diff.getOldMode.toString, oldMode = diff.getOldMode.toString,
newMode = diff.getNewMode.toString, newMode = diff.getNewMode.toString,
tooLarge = false tooLarge = false,
patch = (if(makePatch) Some(makePatchFromDiffEntry(git, diff)) else None)
) )
} }
} }
}.toList }.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. * Returns the list of branch names of the specified commit.