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 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),
logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext)
repo.html.commits(Nil, branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext),
logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext)
}
}
/**
@@ -142,12 +144,14 @@ class RepositoryViewerController extends ControllerBase {
val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "")
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),
logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext)
repo.html.commits(path.split("/").toList, branchName, JGitUtil.getRepositoryInfo(owner, repository, servletContext),
logs.splitWith{ (commit1, commit2) =>
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
}, page, hasNext)
}
}
@@ -162,33 +166,34 @@ class RepositoryViewerController extends ControllerBase {
val path = multiParams("splat").head //.replaceFirst("^tree/.+?/", "")
val repositoryInfo = JGitUtil.getRepositoryInfo(owner, repository, servletContext)
val git = Git.open(getRepositoryDir(owner, repository))
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
JGitUtil.withGit(getRepositoryDir(owner, repository)){ git =>
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
@scala.annotation.tailrec
def getPathObjectId(path: String, walk: TreeWalk): ObjectId = walk.next match {
case true if(walk.getPathString == path) => walk.getObjectId(0)
case true => getPathObjectId(path, walk)
}
@scala.annotation.tailrec
def getPathObjectId(path: String, walk: TreeWalk): ObjectId = walk.next match {
case true if(walk.getPathString == path) => walk.getObjectId(0)
case true => getPathObjectId(path, walk)
}
val treeWalk = new TreeWalk(git.getRepository)
treeWalk.addTree(revCommit.getTree)
treeWalk.setRecursive(true)
val objectId = getPathObjectId(path, treeWalk)
treeWalk.release
val treeWalk = new TreeWalk(git.getRepository)
treeWalk.addTree(revCommit.getTree)
treeWalk.setRecursive(true)
val objectId = getPathObjectId(path, treeWalk)
treeWalk.release
if(raw){
// Download
contentType = "application/octet-stream"
JGitUtil.getContent(git, objectId, false).get
if(raw){
// Download
contentType = "application/octet-stream"
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 {
// 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))
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 id = params("id")
val git = Git.open(getRepositoryDir(owner, repository))
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
repo.html.commit(id, new CommitInfo(revCommit), JGitUtil.getRepositoryInfo(owner, repository, servletContext), JGitUtil.getDiffs(git, id))
JGitUtil.withGit(getRepositoryDir(owner, repository)){ git =>
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
repo.html.commit(id, new CommitInfo(revCommit),
JGitUtil.getRepositoryInfo(owner, repository, servletContext), JGitUtil.getDiffs(git, id))
}
}
/**
@@ -234,14 +240,14 @@ class RepositoryViewerController extends ControllerBase {
// clone the repository
val cloneDir = new File(workDir, revision)
val git = Git.cloneRepository
.setURI(getRepositoryDir(owner, repository).toURI.toString)
.setDirectory(cloneDir)
.call
JGitUtil.withGit(Git.cloneRepository
.setURI(getRepositoryDir(owner, repository).toURI.toString)
.setDirectory(cloneDir)
.call){ git =>
// checkout the specified revision
git.checkout.setName(revision).call
git.getRepository.close
// checkout the specified revision
git.checkout.setName(revision).call
}
// remove .git
FileUtils.deleteDirectory(new File(cloneDir, ".git"))
@@ -273,32 +279,32 @@ class RepositoryViewerController extends ControllerBase {
revstr
}
val git = Git.open(getRepositoryDir(owner, repository))
// get latest commit
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision))
JGitUtil.withGit(getRepositoryDir(owner, repository)){ git =>
// get latest commit
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(revision))
val files = JGitUtil.getFileList(git, revision, path)
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
val readme = files.find(_.name == "README.md").map { file =>
new String(JGitUtil.getContent(Git.open(getRepositoryDir(owner, repository)), file.id, true).get, "UTF-8")
}
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
)
}
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 repository = params("repository")
val page = params("page")
val git = Git.open(WikiUtil.getWikiRepositoryDir(owner, repository))
wiki.html.wikihistory(Some(page),
JGitUtil.getCommitLog(git, "master", path = page + ".md")._1,
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git =>
wiki.html.wikihistory(Some(page),
JGitUtil.getCommitLog(git, "master", path = page + ".md")._1,
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
}
}
get("/:owner/:repository/wiki/:page/_compare/:commitId"){
@@ -58,12 +59,11 @@ class WikiController extends ControllerBase {
val page = params("page")
val commitId = params("commitId").split("\\.\\.\\.")
println(commitId(0))
println(commitId(1))
wiki.html.wikicompare(Some(page),
WikiUtil.getDiffs(Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)), commitId(0), commitId(1)),
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git =>
wiki.html.wikicompare(Some(page),
WikiUtil.getDiffs(git, commitId(0), commitId(1)),
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
}
}
get("/:owner/:repository/wiki/_compare/:commitId"){
@@ -71,12 +71,11 @@ class WikiController extends ControllerBase {
val repository = params("repository")
val commitId = params("commitId").split("\\.\\.\\.")
println(commitId(0))
println(commitId(1))
wiki.html.wikicompare(None,
WikiUtil.getDiffs(Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)), commitId(0), commitId(1)),
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git =>
wiki.html.wikicompare(None,
WikiUtil.getDiffs(git, commitId(0), commitId(1)),
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
}
}
get("/:owner/:repository/wiki/:page/_edit"){
@@ -139,9 +138,11 @@ class WikiController extends ControllerBase {
val owner = params("owner")
val repository = params("repository")
wiki.html.wikihistory(None,
JGitUtil.getCommitLog(Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)), "master")._1,
JGitUtil.withGit(WikiUtil.getWikiRepositoryDir(owner, repository)){ git =>
wiki.html.wikihistory(None,
JGitUtil.getCommitLog(git, "master")._1,
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
}
}
post("/:owner/:repository/wiki/_preview"){

View File

@@ -5,28 +5,39 @@ import app.{RepositoryInfo, FileInfo, CommitInfo, DiffInfo, TagInfo}
import util.Directory._
import scala.collection.JavaConverters._
import javax.servlet.ServletContext
import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.lib.ObjectId
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.lib._
import org.eclipse.jgit.revwalk._
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.
*/
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.
*
@@ -45,19 +56,20 @@ object JGitUtil {
* Returns the repository information. It contains branch names and tag names.
*/
def getRepositoryInfo(owner: String, repository: String, servletContext: ServletContext): RepositoryInfo = {
val git = Git.open(getRepositoryDir(owner, repository))
RepositoryInfo(
owner, repository, "http://localhost:8080%s/git/%s/%s.git".format(servletContext.getContextPath, owner, repository),
// branches
git.branchList.call.asScala.map { ref =>
ref.getName.replaceFirst("^refs/heads/", "")
}.toList,
// tags
git.tagList.call.asScala.map { ref =>
val revCommit = getRevCommitFromId(git, ref.getObjectId)
TagInfo(ref.getName.replaceFirst("^refs/tags/", ""), revCommit.getCommitterIdent.getWhen, revCommit.getName)
}.toList
)
withGit(getRepositoryDir(owner, repository)){ git =>
RepositoryInfo(
owner, repository, "http://localhost:8080%s/git/%s/%s.git".format(servletContext.getContextPath, owner, repository),
// branches
git.branchList.call.asScala.map { ref =>
ref.getName.replaceFirst("^refs/heads/", "")
}.toList,
// tags
git.tagList.call.asScala.map { ref =>
val revCommit = getRevCommitFromId(git, ref.getObjectId)
TagInfo(ref.getName.replaceFirst("^refs/tags/", ""), revCommit.getCommitterIdent.getWhen, revCommit.getName)
}.toList
)
}
}
/**

View File

@@ -51,8 +51,12 @@ object WikiUtil {
val dir = getWikiRepositoryDir(owner, repository)
if(!dir.exists){
val repo = new RepositoryBuilder().setGitDir(dir).setBare.build
repo.create
savePage(owner, repository, "Home", "Home", "Welcome to the %s wiki!!".format(repository), owner, "Initial Commit")
try {
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.
createWikiRepository(owner, repository)
val git = Git.open(getWikiRepositoryDir(owner, repository))
try {
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)
JGitUtil.withGit(getWikiRepositoryDir(owner, repository)){ git =>
try {
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)
}
} 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
val cloned = Git.open(workDir)
val file = new File(workDir, newPageName + ".md")
val added = if(!file.exists || FileUtils.readFileToString(file, "UTF-8") != content){
FileUtils.writeStringToFile(file, content, "UTF-8")
cloned.add.addFilepattern(file.getName).call
true
} else {
false
}
JGitUtil.withGit(workDir){ git =>
val file = new File(workDir, newPageName + ".md")
val added = if(!file.exists || FileUtils.readFileToString(file, "UTF-8") != content){
FileUtils.writeStringToFile(file, content, "UTF-8")
git.add.addFilepattern(file.getName).call
true
} else {
false
}
// delete file
val deleted = if(currentPageName != "" && currentPageName != newPageName){
cloned.rm.addFilepattern(currentPageName + ".md").call
true
} else {
false
}
// delete file
val deleted = if(currentPageName != "" && currentPageName != newPageName){
git.rm.addFilepattern(currentPageName + ".md").call
true
} else {
false
}
// commit and push
if(added || deleted){
// TODO committer's mail address
cloned.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call
cloned.push.call
// commit and push
if(added || deleted){
// TODO committer's mail address
git.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call
git.push.call
}
}
}
@@ -142,13 +148,14 @@ object WikiUtil {
// delete file
new File(workDir, pageName + ".md").delete
val cloned = Git.open(workDir)
cloned.rm.addFilepattern(pageName + ".md").call
JGitUtil.withGit(workDir){ git =>
git.rm.addFilepattern(pageName + ".md").call
// commit and push
// TODO committer's mail address
cloned.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call
cloned.push.call
// commit and push
// TODO committer's mail address
git.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call
git.push.call
}
}
def getDiffs(git: Git, commitId1: String, commitId2: String): List[DiffInfo] = {