Add JGitUtil#withGit() and use it to release repository resources

certainly.
This commit is contained in:
takezoe
2013-05-05 04:58:11 +09:00
parent 1e7f7404dc
commit e7d2455152
4 changed files with 175 additions and 149 deletions

View File

@@ -124,12 +124,14 @@ class RepositoryViewerController extends ControllerBase {
val branchName = params("branch") val branchName = params("branch")
val page = params.getOrElse("page", "1").toInt val page = params.getOrElse("page", "1").toInt
val (logs, hasNext) = JGitUtil.getCommitLog(Git.open(getRepositoryDir(owner, repository)), branchName, page, 30) JGitUtil.withGit(getRepositoryDir(owner, repository)){ git =>
val (logs, hasNext) = JGitUtil.getCommitLog(git, branchName, page, 30)
repo.html.commits(Nil, branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext), repo.html.commits(Nil, branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext),
logs.splitWith{ (commit1, commit2) => logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time) view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext) }, page, hasNext)
}
} }
/** /**
@@ -142,12 +144,14 @@ class RepositoryViewerController extends ControllerBase {
val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "") val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "")
val page = params.getOrElse("page", "1").toInt val page = params.getOrElse("page", "1").toInt
val (logs, hasNext) = JGitUtil.getCommitLog(Git.open(getRepositoryDir(owner, repository)), branchName, page, 30, path) JGitUtil.withGit(getRepositoryDir(owner, repository)){ git =>
val (logs, hasNext) = JGitUtil.getCommitLog(git, branchName, page, 30, path)
repo.html.commits(path.split("/").toList, branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext), repo.html.commits(path.split("/").toList, branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext),
logs.splitWith{ (commit1, commit2) => logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time) view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext) }, page, hasNext)
}
} }
@@ -162,33 +166,34 @@ class RepositoryViewerController extends ControllerBase {
val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "") val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "")
val repositoryInfo = JGitUtil.getRepositoryInfo(owner, repository, servletContext) val repositoryInfo = JGitUtil.getRepositoryInfo(owner, repository, servletContext)
val git = Git.open(getRepositoryDir(owner, repository)) JGitUtil.withGit(getRepositoryDir(owner, repository)){ git =>
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id)) val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
@scala.annotation.tailrec @scala.annotation.tailrec
def getPathObjectId(path: String, walk: TreeWalk): ObjectId = walk.next match { def getPathObjectId(path: String, walk: TreeWalk): ObjectId = walk.next match {
case true if(walk.getPathString == path) => walk.getObjectId(0) case true if(walk.getPathString == path) => walk.getObjectId(0)
case true => getPathObjectId(path, walk) case true => getPathObjectId(path, walk)
} }
val treeWalk = new TreeWalk(git.getRepository) val treeWalk = new TreeWalk(git.getRepository)
treeWalk.addTree(revCommit.getTree) treeWalk.addTree(revCommit.getTree)
treeWalk.setRecursive(true) treeWalk.setRecursive(true)
val objectId = getPathObjectId(path, treeWalk) val objectId = getPathObjectId(path, treeWalk)
treeWalk.release treeWalk.release
if(raw){ if(raw){
// Download // Download
contentType = "application/octet-stream" contentType = "application/octet-stream"
JGitUtil.getContent(git, objectId, false).get JGitUtil.getContent(git, objectId, false).get
} else {
// Viewer
val large = FileTypeUtil.isLarge(git.getRepository.getObjectDatabase.open(objectId).getSize)
val viewer = if(FileTypeUtil.isImage(path)) "image" else if(large) "large" else "text"
val content = ContentInfo(viewer,
if(viewer == "text") JGitUtil.getContent(git, objectId, false).map(new String(_, "UTF-8")) else None)
} else { repo.html.blob(id, repositoryInfo, path.split("/").toList, content, new CommitInfo(revCommit))
// Viewer }
val large = FileTypeUtil.isLarge(git.getRepository.getObjectDatabase.open(objectId).getSize)
val viewer = if(FileTypeUtil.isImage(path)) "image" else if(large) "large" else "text"
val content = ContentInfo(viewer, if(viewer == "text") JGitUtil.getContent(git, objectId, false).map(new String(_, "UTF-8")) else None)
repo.html.blob(id, repositoryInfo, path.split("/").toList, content, new CommitInfo(revCommit))
} }
} }
@@ -200,10 +205,11 @@ class RepositoryViewerController extends ControllerBase {
val repository = params("repository") val repository = params("repository")
val id = params("id") val id = params("id")
val git = Git.open(getRepositoryDir(owner, repository)) JGitUtil.withGit(getRepositoryDir(owner, repository)){ git =>
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id)) val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
repo.html.commit(id, new CommitInfo(revCommit),
repo.html.commit(id, new CommitInfo(revCommit), JGitUtil.getRepositoryInfo(owner, repository, servletContext), JGitUtil.getDiffs(git, id)) JGitUtil.getRepositoryInfo(owner, repository, servletContext), JGitUtil.getDiffs(git, id))
}
} }
/** /**
@@ -234,14 +240,14 @@ class RepositoryViewerController extends ControllerBase {
// clone the repository // clone the repository
val cloneDir = new File(workDir, revision) val cloneDir = new File(workDir, revision)
val git = Git.cloneRepository JGitUtil.withGit(Git.cloneRepository
.setURI(getRepositoryDir(owner, repository).toURI.toString) .setURI(getRepositoryDir(owner, repository).toURI.toString)
.setDirectory(cloneDir) .setDirectory(cloneDir)
.call .call){ git =>
// checkout the specified revision // checkout the specified revision
git.checkout.setName(revision).call git.checkout.setName(revision).call
git.getRepository.close }
// remove .git // remove .git
FileUtils.deleteDirectory(new File(cloneDir, ".git")) FileUtils.deleteDirectory(new File(cloneDir, ".git"))
@@ -273,32 +279,32 @@ class RepositoryViewerController extends ControllerBase {
revstr revstr
} }
val git = Git.open(getRepositoryDir(owner, repository)) JGitUtil.withGit(getRepositoryDir(owner, repository)){ git =>
// get latest commit
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision))
// get latest commit val files = JGitUtil.getFileList(git, revision, path)
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision))
val files = JGitUtil.getFileList(git, revision, path) // process README.md
val readme = files.find(_.name == "README.md").map { file =>
new String(JGitUtil.getContent(Git.open(getRepositoryDir(owner, repository)), file.id, true).get, "UTF-8")
}
// process README.md repo.html.files(
val readme = files.find(_.name == "README.md").map { file => // current branch
new String(JGitUtil.getContent(Git.open(getRepositoryDir(owner, repository)), file.id, true).get, "UTF-8") revision,
// repository
JGitUtil.getRepositoryInfo(owner, repository, servletContext),
// current path
if(path == ".") Nil else path.split("/").toList,
// latest commit
new CommitInfo(revCommit),
// file list
files,
// readme
readme
)
} }
repo.html.files(
// current branch
revision,
// repository
JGitUtil.getRepositoryInfo(owner, repository, servletContext),
// current path
if(path == ".") Nil else path.split("/").toList,
// latest commit
new CommitInfo(revCommit),
// file list
files,
// readme
readme
)
} }
} }

View File

@@ -45,11 +45,12 @@ class WikiController extends ControllerBase {
val owner = params("owner") val owner = params("owner")
val repository = params("repository") val repository = params("repository")
val page = params("page") val page = params("page")
val git = Git.open(WikiUtil.getWikiRepositoryDir(owner, repository))
wiki.html.wikihistory(Some(page), JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git =>
JGitUtil.getCommitLog(git, "master", path = page + ".md")._1, wiki.html.wikihistory(Some(page),
JGitUtil.getRepositoryInfo(owner, repository, servletContext)) JGitUtil.getCommitLog(git, "master", path = page + ".md")._1,
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
}
} }
get("/:owner/:repository/wiki/:page/_compare/:commitId"){ get("/:owner/:repository/wiki/:page/_compare/:commitId"){
@@ -58,12 +59,11 @@ class WikiController extends ControllerBase {
val page = params("page") val page = params("page")
val commitId = params("commitId").split("\\.\\.\\.") val commitId = params("commitId").split("\\.\\.\\.")
println(commitId(0)) JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git =>
println(commitId(1)) wiki.html.wikicompare(Some(page),
WikiUtil.getDiffs(git, commitId(0), commitId(1)),
wiki.html.wikicompare(Some(page), JGitUtil.getRepositoryInfo(owner, repository, servletContext))
WikiUtil.getDiffs(Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)), commitId(0), commitId(1)), }
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
} }
get("/:owner/:repository/wiki/_compare/:commitId"){ get("/:owner/:repository/wiki/_compare/:commitId"){
@@ -71,12 +71,11 @@ class WikiController extends ControllerBase {
val repository = params("repository") val repository = params("repository")
val commitId = params("commitId").split("\\.\\.\\.") val commitId = params("commitId").split("\\.\\.\\.")
println(commitId(0)) JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git =>
println(commitId(1)) wiki.html.wikicompare(None,
WikiUtil.getDiffs(git, commitId(0), commitId(1)),
wiki.html.wikicompare(None, JGitUtil.getRepositoryInfo(owner, repository, servletContext))
WikiUtil.getDiffs(Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)), commitId(0), commitId(1)), }
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
} }
get("/:owner/:repository/wiki/:page/_edit"){ get("/:owner/:repository/wiki/:page/_edit"){
@@ -139,9 +138,11 @@ class WikiController extends ControllerBase {
val owner = params("owner") val owner = params("owner")
val repository = params("repository") val repository = params("repository")
wiki.html.wikihistory(None, JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git =>
JGitUtil.getCommitLog(Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)), "master")._1, wiki.html.wikihistory(None,
JGitUtil.getCommitLog(git, "master")._1,
JGitUtil.getRepositoryInfo(owner, repository, servletContext)) JGitUtil.getRepositoryInfo(owner, repository, servletContext))
}
} }
post("/:owner/:repository/wiki/_preview"){ post("/:owner/:repository/wiki/_preview"){

View File

@@ -5,28 +5,39 @@ import app.{RepositoryInfo, FileInfo, CommitInfo, DiffInfo, TagInfo}
import util.Directory._ import util.Directory._
import scala.collection.JavaConverters._ import scala.collection.JavaConverters._
import javax.servlet.ServletContext import javax.servlet.ServletContext
import org.eclipse.jgit.lib.Ref import org.eclipse.jgit.lib._
import org.eclipse.jgit.lib.ObjectId import org.eclipse.jgit.revwalk._
import org.eclipse.jgit.errors.MissingObjectException
import org.eclipse.jgit.revwalk.RevCommit
import org.eclipse.jgit.diff.DiffFormatter
import org.eclipse.jgit.treewalk.TreeWalk
import org.eclipse.jgit.revwalk.RevWalk
import org.eclipse.jgit.diff.RawTextComparator
import org.eclipse.jgit.util.io.DisabledOutputStream
import org.eclipse.jgit.lib.Repository
import org.eclipse.jgit.revwalk.RevSort
import org.eclipse.jgit.diff.DiffEntry.ChangeType
import org.eclipse.jgit.lib.FileMode
import org.eclipse.jgit.treewalk.filter.PathFilter
import org.eclipse.jgit.treewalk.CanonicalTreeParser
import org.eclipse.jgit.revwalk.filter.RevFilter import org.eclipse.jgit.revwalk.filter.RevFilter
import org.eclipse.jgit.treewalk._
import org.eclipse.jgit.treewalk.filter.PathFilter
import org.eclipse.jgit.diff._
import org.eclipse.jgit.diff.DiffEntry.ChangeType
import org.eclipse.jgit.util.io.DisabledOutputStream
import org.eclipse.jgit.errors.MissingObjectException
/** /**
* Provides complex JGit operations. * Provides complex JGit operations.
*/ */
object JGitUtil { object JGitUtil {
/**
* Use this method to use the Git object.
* Repository resources are released certainly after processing.
*/
def withGit[T](dir: java.io.File)(f: Git => T): T = withGit(Git.open(dir))(f)
/**
* Use this method to use the Git object.
* Repository resources are released certainly after processing.
*/
def withGit[T](git: Git)(f: Git => T): T = {
try {
f(git)
} finally {
git.getRepository.close
}
}
/** /**
* Returns RevCommit from the commit id. * Returns RevCommit from the commit id.
* *
@@ -45,19 +56,20 @@ object JGitUtil {
* Returns the repository information. It contains branch names and tag names. * Returns the repository information. It contains branch names and tag names.
*/ */
def getRepositoryInfo(owner: String, repository: String, servletContext: ServletContext): RepositoryInfo = { def getRepositoryInfo(owner: String, repository: String, servletContext: ServletContext): RepositoryInfo = {
val git = Git.open(getRepositoryDir(owner, repository)) withGit(getRepositoryDir(owner, repository)){ git =>
RepositoryInfo( RepositoryInfo(
owner, repository, "http://localhost:8080%s/git/%s/%s.git".format(servletContext.getContextPath, owner, repository), owner, repository, "http://localhost:8080%s/git/%s/%s.git".format(servletContext.getContextPath, owner, repository),
// branches // branches
git.branchList.call.asScala.map { ref => git.branchList.call.asScala.map { ref =>
ref.getName.replaceFirst("^refs/heads/", "") ref.getName.replaceFirst("^refs/heads/", "")
}.toList, }.toList,
// tags // tags
git.tagList.call.asScala.map { ref => git.tagList.call.asScala.map { ref =>
val revCommit = getRevCommitFromId(git, ref.getObjectId) val revCommit = getRevCommitFromId(git, ref.getObjectId)
TagInfo(ref.getName.replaceFirst("^refs/tags/", ""), revCommit.getCommitterIdent.getWhen, revCommit.getName) TagInfo(ref.getName.replaceFirst("^refs/tags/", ""), revCommit.getCommitterIdent.getWhen, revCommit.getName)
}.toList }.toList
) )
}
} }
/** /**

View File

@@ -51,8 +51,12 @@ object WikiUtil {
val dir = getWikiRepositoryDir(owner, repository) val dir = getWikiRepositoryDir(owner, repository)
if(!dir.exists){ if(!dir.exists){
val repo = new RepositoryBuilder().setGitDir(dir).setBare.build val repo = new RepositoryBuilder().setGitDir(dir).setBare.build
repo.create try {
savePage(owner, repository, "Home", "Home", "Welcome to the %s wiki!!".format(repository), owner, "Initial Commit") repo.create
savePage(owner, repository, "Home", "Home", "Welcome to the %s wiki!!".format(repository), owner, "Initial Commit")
} finally {
repo.close
}
} }
} }
@@ -63,14 +67,15 @@ object WikiUtil {
// TODO create wiki repository in the repository setting changing. // TODO create wiki repository in the repository setting changing.
createWikiRepository(owner, repository) createWikiRepository(owner, repository)
val git = Git.open(getWikiRepositoryDir(owner, repository)) JGitUtil.withGit(getWikiRepositoryDir(owner, repository)){ git =>
try { try {
JGitUtil.getFileList(git, "master", ".").find(_.name == pageName + ".md").map { file => JGitUtil.getFileList(git, "master", ".").find(_.name == pageName + ".md").map { file =>
WikiPageInfo(file.name, new String(git.getRepository.open(file.id).getBytes, "UTF-8"), file.committer, file.time) WikiPageInfo(file.name, new String(git.getRepository.open(file.id).getBytes, "UTF-8"), file.committer, file.time)
}
} catch {
// TODO no commit, but it should not judge by exception.
case e: NullPointerException => None
} }
} catch {
// TODO no commit, but it should not judge by exception.
case e: NullPointerException => None
} }
} }
@@ -99,29 +104,30 @@ object WikiUtil {
} }
// write as file // write as file
val cloned = Git.open(workDir) JGitUtil.withGit(workDir){ git =>
val file = new File(workDir, newPageName + ".md") val file = new File(workDir, newPageName + ".md")
val added = if(!file.exists || FileUtils.readFileToString(file, "UTF-8") != content){ val added = if(!file.exists || FileUtils.readFileToString(file, "UTF-8") != content){
FileUtils.writeStringToFile(file, content, "UTF-8") FileUtils.writeStringToFile(file, content, "UTF-8")
cloned.add.addFilepattern(file.getName).call git.add.addFilepattern(file.getName).call
true true
} else { } else {
false false
} }
// delete file // delete file
val deleted = if(currentPageName != "" && currentPageName != newPageName){ val deleted = if(currentPageName != "" && currentPageName != newPageName){
cloned.rm.addFilepattern(currentPageName + ".md").call git.rm.addFilepattern(currentPageName + ".md").call
true true
} else { } else {
false false
} }
// commit and push // commit and push
if(added || deleted){ if(added || deleted){
// TODO committer's mail address // TODO committer's mail address
cloned.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call git.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call
cloned.push.call git.push.call
}
} }
} }
@@ -142,13 +148,14 @@ object WikiUtil {
// delete file // delete file
new File(workDir, pageName + ".md").delete new File(workDir, pageName + ".md").delete
val cloned = Git.open(workDir) JGitUtil.withGit(workDir){ git =>
cloned.rm.addFilepattern(pageName + ".md").call git.rm.addFilepattern(pageName + ".md").call
// commit and push // commit and push
// TODO committer's mail address // TODO committer's mail address
cloned.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call git.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call
cloned.push.call git.push.call
}
} }
def getDiffs(git: Git, commitId1: String, commitId2: String): List[DiffInfo] = { def getDiffs(git: Git, commitId1: String, commitId2: String): List[DiffInfo] = {