mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-06 05:25:50 +01:00
Improve repository creation to not use the working repository.
This commit is contained in:
@@ -8,7 +8,8 @@ import java.io.File
|
|||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.apache.commons.io._
|
import org.apache.commons.io._
|
||||||
import jp.sf.amateras.scalatra.forms._
|
import jp.sf.amateras.scalatra.forms._
|
||||||
import org.eclipse.jgit.lib.PersonIdent
|
import org.eclipse.jgit.lib.{FileMode, Constants, PersonIdent}
|
||||||
|
import org.eclipse.jgit.dircache.DirCache
|
||||||
|
|
||||||
class CreateRepositoryController extends CreateRepositoryControllerBase
|
class CreateRepositoryController extends CreateRepositoryControllerBase
|
||||||
with RepositoryService with AccountService with WikiService with LabelsService with ActivityService
|
with RepositoryService with AccountService with WikiService with LabelsService with ActivityService
|
||||||
@@ -73,28 +74,26 @@ trait CreateRepositoryControllerBase extends ControllerBase {
|
|||||||
JGitUtil.initRepository(gitdir)
|
JGitUtil.initRepository(gitdir)
|
||||||
|
|
||||||
if(form.createReadme){
|
if(form.createReadme){
|
||||||
FileUtil.withTmpDir(getInitRepositoryDir(form.owner, form.name)){ tmpdir =>
|
using(Git.open(gitdir)){ git =>
|
||||||
// Clone the repository
|
val builder = DirCache.newInCore.builder()
|
||||||
Git.cloneRepository.setURI(gitdir.toURI.toString).setDirectory(tmpdir).call
|
val inserter = git.getRepository.newObjectInserter()
|
||||||
|
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
||||||
|
val content = if(form.description.nonEmpty){
|
||||||
|
form.name + "\n" +
|
||||||
|
"===============\n" +
|
||||||
|
"\n" +
|
||||||
|
form.description.get
|
||||||
|
} else {
|
||||||
|
form.name + "\n" +
|
||||||
|
"===============\n"
|
||||||
|
}
|
||||||
|
|
||||||
// Create README.md
|
builder.add(JGitUtil.createDirCacheEntry("README.md", FileMode.REGULAR_FILE,
|
||||||
FileUtils.writeStringToFile(new File(tmpdir, "README.md"),
|
inserter.insert(Constants.OBJ_BLOB, content.getBytes("UTF-8"))))
|
||||||
if(form.description.nonEmpty){
|
builder.finish()
|
||||||
form.name + "\n" +
|
|
||||||
"===============\n" +
|
|
||||||
"\n" +
|
|
||||||
form.description.get
|
|
||||||
} else {
|
|
||||||
form.name + "\n" +
|
|
||||||
"===============\n"
|
|
||||||
}, "UTF-8")
|
|
||||||
|
|
||||||
val git = Git.open(tmpdir)
|
JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter),
|
||||||
git.add.addFilepattern("README.md").call
|
loginAccount.fullName, loginAccount.mailAddress, "Initial commit")
|
||||||
git.commit
|
|
||||||
.setCommitter(new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
|
|
||||||
.setMessage("Initial commit").call
|
|
||||||
git.push.call
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,18 +176,18 @@ trait WikiService {
|
|||||||
val path = treeWalk.getPathString
|
val path = treeWalk.getPathString
|
||||||
val tree = treeWalk.getTree(index, classOf[CanonicalTreeParser])
|
val tree = treeWalk.getTree(index, classOf[CanonicalTreeParser])
|
||||||
if(revertInfo.find(x => x.filePath == path).isEmpty){
|
if(revertInfo.find(x => x.filePath == path).isEmpty){
|
||||||
builder.add(createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
|
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
revertInfo.filter(_.operation == "ADD").foreach { x =>
|
revertInfo.filter(_.operation == "ADD").foreach { x =>
|
||||||
builder.add(createDirCacheEntry(x.filePath, FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, x.source.getBytes("UTF-8"))))
|
builder.add(JGitUtil.createDirCacheEntry(x.filePath, FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, x.source.getBytes("UTF-8"))))
|
||||||
}
|
}
|
||||||
builder.finish()
|
builder.finish()
|
||||||
|
|
||||||
createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter), committer.fullName, committer.mailAddress,
|
JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter), committer.fullName, committer.mailAddress,
|
||||||
pageName match {
|
pageName match {
|
||||||
case Some(x) => s"Revert ${from} ... ${to} on ${x}"
|
case Some(x) => s"Revert ${from} ... ${to} on ${x}"
|
||||||
case None => s"Revert ${from} ... ${to}"
|
case None => s"Revert ${from} ... ${to}"
|
||||||
@@ -218,29 +218,31 @@ trait WikiService {
|
|||||||
var updated = false
|
var updated = false
|
||||||
var removed = false
|
var removed = false
|
||||||
|
|
||||||
using(new RevWalk(git.getRepository)){ revWalk =>
|
if(headId != null){
|
||||||
using(new TreeWalk(git.getRepository)){ treeWalk =>
|
using(new RevWalk(git.getRepository)){ revWalk =>
|
||||||
val index = treeWalk.addTree(revWalk.parseTree(headId))
|
using(new TreeWalk(git.getRepository)){ treeWalk =>
|
||||||
treeWalk.setRecursive(true)
|
val index = treeWalk.addTree(revWalk.parseTree(headId))
|
||||||
while(treeWalk.next){
|
treeWalk.setRecursive(true)
|
||||||
val path = treeWalk.getPathString
|
while(treeWalk.next){
|
||||||
val tree = treeWalk.getTree(index, classOf[CanonicalTreeParser])
|
val path = treeWalk.getPathString
|
||||||
if(path == currentPageName + ".md" && currentPageName != newPageName){
|
val tree = treeWalk.getTree(index, classOf[CanonicalTreeParser])
|
||||||
removed = true
|
if(path == currentPageName + ".md" && currentPageName != newPageName){
|
||||||
} else if(path != newPageName + ".md"){
|
removed = true
|
||||||
builder.add(createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
|
} else if(path != newPageName + ".md"){
|
||||||
} else {
|
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
|
||||||
created = false
|
} else {
|
||||||
updated = JGitUtil.getContent(git, tree.getEntryObjectId, true).map(new String(_, "UTF-8") != content).getOrElse(false)
|
created = false
|
||||||
|
updated = JGitUtil.getContent(git, tree.getEntryObjectId, true).map(new String(_, "UTF-8") != content).getOrElse(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
optionIf(created || updated || removed){
|
optionIf(created || updated || removed){
|
||||||
builder.add(createDirCacheEntry(newPageName + ".md", FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, content.getBytes("UTF-8"))))
|
builder.add(JGitUtil.createDirCacheEntry(newPageName + ".md", FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, content.getBytes("UTF-8"))))
|
||||||
builder.finish()
|
builder.finish()
|
||||||
val newHeadId = createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter), committer.fullName, committer.mailAddress,
|
val newHeadId = JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter), committer.fullName, committer.mailAddress,
|
||||||
if(message.trim.length == 0) {
|
if(message.trim.length == 0) {
|
||||||
if(removed){
|
if(removed){
|
||||||
s"Rename ${currentPageName} to ${newPageName}"
|
s"Rename ${currentPageName} to ${newPageName}"
|
||||||
@@ -279,7 +281,7 @@ trait WikiService {
|
|||||||
val path = treeWalk.getPathString
|
val path = treeWalk.getPathString
|
||||||
val tree = treeWalk.getTree(index, classOf[CanonicalTreeParser])
|
val tree = treeWalk.getTree(index, classOf[CanonicalTreeParser])
|
||||||
if(path != pageName + ".md"){
|
if(path != pageName + ".md"){
|
||||||
builder.add(createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
|
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
|
||||||
} else {
|
} else {
|
||||||
removed = true
|
removed = true
|
||||||
}
|
}
|
||||||
@@ -288,39 +290,11 @@ trait WikiService {
|
|||||||
|
|
||||||
if(removed){
|
if(removed){
|
||||||
builder.finish()
|
builder.finish()
|
||||||
createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter), committer, mailAddress, message)
|
JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter), committer, mailAddress, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method should be moved to JGitUtil?
|
|
||||||
private def createDirCacheEntry(path: String, mode: FileMode, objectId: ObjectId): DirCacheEntry = {
|
|
||||||
val entry = new DirCacheEntry(path)
|
|
||||||
entry.setFileMode(mode)
|
|
||||||
entry.setObjectId(objectId)
|
|
||||||
entry
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method should be moved to JGitUtil?
|
|
||||||
private def createNewCommit(git: Git, inserter: ObjectInserter, headId: AnyObjectId, treeId: AnyObjectId,
|
|
||||||
fullName: String, mailAddress: String, message: String): String = {
|
|
||||||
val newCommit = new CommitBuilder()
|
|
||||||
newCommit.setCommitter(new PersonIdent(fullName, mailAddress))
|
|
||||||
newCommit.setAuthor(new PersonIdent(fullName, mailAddress))
|
|
||||||
newCommit.setMessage(message)
|
|
||||||
newCommit.setParentIds(List(headId).asJava)
|
|
||||||
newCommit.setTreeId(treeId)
|
|
||||||
|
|
||||||
val newHeadId = inserter.insert(newCommit)
|
|
||||||
inserter.flush()
|
|
||||||
|
|
||||||
val refUpdate = git.getRepository.updateRef(Constants.HEAD)
|
|
||||||
refUpdate.setNewObjectId(newHeadId)
|
|
||||||
refUpdate.update()
|
|
||||||
|
|
||||||
newHeadId.getName
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,15 +56,6 @@ object Directory {
|
|||||||
def getDownloadWorkDir(owner: String, repository: String, sessionId: String): File =
|
def getDownloadWorkDir(owner: String, repository: String, sessionId: String): File =
|
||||||
new File(getTemporaryDir(owner, repository), s"download/${sessionId}")
|
new File(getTemporaryDir(owner, repository), s"download/${sessionId}")
|
||||||
|
|
||||||
/**
|
|
||||||
* Temporary directory which is used in the repository creation.
|
|
||||||
*
|
|
||||||
* GitBucket generates initial repository contents in this directory and push them.
|
|
||||||
* This directory is removed after the repository creation.
|
|
||||||
*/
|
|
||||||
def getInitRepositoryDir(owner: String, repository: String): File =
|
|
||||||
new File(getTemporaryDir(owner, repository), "init")
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Substance directory of the wiki repository.
|
* Substance directory of the wiki repository.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.eclipse.jgit.errors.MissingObjectException
|
|||||||
import java.util.Date
|
import java.util.Date
|
||||||
import org.eclipse.jgit.api.errors.NoHeadException
|
import org.eclipse.jgit.api.errors.NoHeadException
|
||||||
import service.RepositoryService
|
import service.RepositoryService
|
||||||
|
import org.eclipse.jgit.dircache.DirCacheEntry
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides complex JGit operations.
|
* Provides complex JGit operations.
|
||||||
@@ -464,4 +465,32 @@ object JGitUtil {
|
|||||||
}.find(_._1 != null)
|
}.find(_._1 != null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def createDirCacheEntry(path: String, mode: FileMode, objectId: ObjectId): DirCacheEntry = {
|
||||||
|
val entry = new DirCacheEntry(path)
|
||||||
|
entry.setFileMode(mode)
|
||||||
|
entry.setObjectId(objectId)
|
||||||
|
entry
|
||||||
|
}
|
||||||
|
|
||||||
|
def createNewCommit(git: Git, inserter: ObjectInserter, headId: AnyObjectId, treeId: AnyObjectId,
|
||||||
|
fullName: String, mailAddress: String, message: String): String = {
|
||||||
|
val newCommit = new CommitBuilder()
|
||||||
|
newCommit.setCommitter(new PersonIdent(fullName, mailAddress))
|
||||||
|
newCommit.setAuthor(new PersonIdent(fullName, mailAddress))
|
||||||
|
newCommit.setMessage(message)
|
||||||
|
if(headId != null){
|
||||||
|
newCommit.setParentIds(List(headId).asJava)
|
||||||
|
}
|
||||||
|
newCommit.setTreeId(treeId)
|
||||||
|
|
||||||
|
val newHeadId = inserter.insert(newCommit)
|
||||||
|
inserter.flush()
|
||||||
|
|
||||||
|
val refUpdate = git.getRepository.updateRef(Constants.HEAD)
|
||||||
|
refUpdate.setNewObjectId(newHeadId)
|
||||||
|
refUpdate.update()
|
||||||
|
|
||||||
|
newHeadId.getName
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user