mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-10-31 18:46:28 +01:00
(refs #13)Commit from AceEditor is available.
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
|
import _root_.util.JGitUtil.CommitInfo
|
||||||
import util.Directory._
|
import util.Directory._
|
||||||
import util.Implicits._
|
import util.Implicits._
|
||||||
import util.ControlUtil._
|
import _root_.util.ControlUtil._
|
||||||
import _root_.util._
|
import _root_.util._
|
||||||
import service._
|
import service._
|
||||||
import org.scalatra._
|
import org.scalatra._
|
||||||
@@ -14,6 +15,7 @@ import org.eclipse.jgit.treewalk._
|
|||||||
import java.util.zip.{ZipEntry, ZipOutputStream}
|
import java.util.zip.{ZipEntry, ZipOutputStream}
|
||||||
import jp.sf.amateras.scalatra.forms._
|
import jp.sf.amateras.scalatra.forms._
|
||||||
import org.eclipse.jgit.dircache.DirCache
|
import org.eclipse.jgit.dircache.DirCache
|
||||||
|
import org.eclipse.jgit.revwalk.RevWalk
|
||||||
|
|
||||||
class RepositoryViewerController extends RepositoryViewerControllerBase
|
class RepositoryViewerController extends RepositoryViewerControllerBase
|
||||||
with RepositoryService with AccountService with ActivityService with ReferrerAuthenticator with CollaboratorsAuthenticator
|
with RepositoryService with AccountService with ActivityService with ReferrerAuthenticator with CollaboratorsAuthenticator
|
||||||
@@ -24,11 +26,12 @@ class RepositoryViewerController extends RepositoryViewerControllerBase
|
|||||||
trait RepositoryViewerControllerBase extends ControllerBase {
|
trait RepositoryViewerControllerBase extends ControllerBase {
|
||||||
self: RepositoryService with AccountService with ActivityService with ReferrerAuthenticator with CollaboratorsAuthenticator =>
|
self: RepositoryService with AccountService with ActivityService with ReferrerAuthenticator with CollaboratorsAuthenticator =>
|
||||||
|
|
||||||
case class EditorForm(content: String, message: Option[String])
|
case class EditorForm(content: String, message: Option[String], charset: String)
|
||||||
|
|
||||||
val editorForm = mapping(
|
val editorForm = mapping(
|
||||||
"content" -> trim(label("Content", text())),
|
"content" -> trim(label("Content", text())),
|
||||||
"message" -> trim(label("Messgae", optional(text())))
|
"message" -> trim(label("Messgae", optional(text()))),
|
||||||
|
"charset" -> trim(label("Charset", text()))
|
||||||
)(EditorForm.apply)
|
)(EditorForm.apply)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,14 +111,14 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
val content = if(viewer == "other"){
|
val content = if(viewer == "other"){
|
||||||
if(bytes.isDefined && FileUtil.isText(bytes.get)){
|
if(bytes.isDefined && FileUtil.isText(bytes.get)){
|
||||||
// text
|
// text
|
||||||
JGitUtil.ContentInfo("text", bytes.map(StringUtil.convertFromByteArray))
|
JGitUtil.ContentInfo("text", Some(StringUtil.convertFromByteArray(bytes.get)), Some(StringUtil.detectEncoding(bytes.get)))
|
||||||
} else {
|
} else {
|
||||||
// binary
|
// binary
|
||||||
JGitUtil.ContentInfo("binary", None)
|
JGitUtil.ContentInfo("binary", None, None)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// image or large
|
// image or large
|
||||||
JGitUtil.ContentInfo(viewer, None)
|
JGitUtil.ContentInfo(viewer, None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.html.editor(id, repository, path.split("/").toList, content, new JGitUtil.CommitInfo(revCommit))
|
repo.html.editor(id, repository, path.split("/").toList, content, new JGitUtil.CommitInfo(revCommit))
|
||||||
@@ -123,22 +126,63 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TODO Share this method with WikiService
|
||||||
|
private def processTree(git: Git, id: ObjectId)(f: (String, CanonicalTreeParser) => Unit) = {
|
||||||
|
using(new RevWalk(git.getRepository)){ revWalk =>
|
||||||
|
using(new TreeWalk(git.getRepository)){ treeWalk =>
|
||||||
|
val index = treeWalk.addTree(revWalk.parseTree(id))
|
||||||
|
treeWalk.setRecursive(true)
|
||||||
|
while(treeWalk.next){
|
||||||
|
f(treeWalk.getPathString, treeWalk.getTree(index, classOf[CanonicalTreeParser]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
post("/:owner/:repository/edit/*", editorForm)(collaboratorsOnly { (form, repository) =>
|
post("/:owner/:repository/edit/*", editorForm)(collaboratorsOnly { (form, repository) =>
|
||||||
// val (id, path) = splitPath(repository, multiParams("splat").head)
|
val (id, path) = splitPath(repository, multiParams("splat").head)
|
||||||
// val loginAccount = context.loginAccount.get
|
|
||||||
//
|
LockUtil.lock(s"${repository.owner}/${repository.name}"){
|
||||||
// using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
|
using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
|
||||||
// val builder = DirCache.newInCore.builder()
|
val loginAccount = context.loginAccount.get
|
||||||
// val inserter = git.getRepository.newObjectInserter()
|
val builder = DirCache.newInCore.builder()
|
||||||
// val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
val inserter = git.getRepository.newObjectInserter()
|
||||||
//
|
val headName = s"refs/heads/${id}"
|
||||||
// builder.add(JGitUtil.createDirCacheEntry(path, FileMode.REGULAR_FILE,
|
val headTip = git.getRepository.resolve(s"refs/heads/${id}")
|
||||||
// inserter.insert(Constants.OBJ_BLOB, form.content.getBytes("UTF-8")))) // TODO charset auto detection
|
|
||||||
// builder.finish()
|
processTree(git, headTip){ (treePath, tree) =>
|
||||||
//
|
if(treePath != path){
|
||||||
// JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter),
|
builder.add(JGitUtil.createDirCacheEntry(treePath, tree.getEntryFileMode, tree.getEntryObjectId))
|
||||||
// loginAccount.fullName, loginAccount.mailAddress, form.message.getOrElse(s"Update ${path.split("/").last}"))
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
builder.add(JGitUtil.createDirCacheEntry(path, FileMode.REGULAR_FILE,
|
||||||
|
inserter.insert(Constants.OBJ_BLOB, form.content.getBytes(form.charset))))
|
||||||
|
builder.finish()
|
||||||
|
|
||||||
|
val commitId = JGitUtil.createNewCommit(git, inserter, headTip, builder.getDirCache.writeTree(inserter),
|
||||||
|
loginAccount.fullName, loginAccount.mailAddress, form.message.getOrElse(s"Update ${path.split("/").last}"))
|
||||||
|
|
||||||
|
inserter.flush()
|
||||||
|
inserter.release()
|
||||||
|
|
||||||
|
// update refs
|
||||||
|
val refUpdate = git.getRepository.updateRef(headName)
|
||||||
|
refUpdate.setNewObjectId(commitId)
|
||||||
|
refUpdate.setForceUpdate(false)
|
||||||
|
refUpdate.setRefLogIdent(new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
|
||||||
|
//refUpdate.setRefLogMessage("merged", true)
|
||||||
|
refUpdate.update()
|
||||||
|
|
||||||
|
// record activity
|
||||||
|
recordPushActivity(repository.owner, repository.name, loginAccount.userName, id,
|
||||||
|
List(new CommitInfo(JGitUtil.getRevCommitFromId(git, commitId))))
|
||||||
|
|
||||||
|
// TODO invoke hook
|
||||||
|
|
||||||
|
redirect(s"/${repository.owner}/${repository.name}/blob/${id}/${path}")
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -178,14 +222,14 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
val content = if(viewer == "other"){
|
val content = if(viewer == "other"){
|
||||||
if(bytes.isDefined && FileUtil.isText(bytes.get)){
|
if(bytes.isDefined && FileUtil.isText(bytes.get)){
|
||||||
// text
|
// text
|
||||||
JGitUtil.ContentInfo("text", bytes.map(StringUtil.convertFromByteArray))
|
JGitUtil.ContentInfo("text", Some(StringUtil.convertFromByteArray(bytes.get)), Some(StringUtil.detectEncoding(bytes.get)))
|
||||||
} else {
|
} else {
|
||||||
// binary
|
// binary
|
||||||
JGitUtil.ContentInfo("binary", None)
|
JGitUtil.ContentInfo("binary", None, None)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// image or large
|
// image or large
|
||||||
JGitUtil.ContentInfo(viewer, None)
|
JGitUtil.ContentInfo(viewer, None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.html.blob(id, repository, path.split("/").toList, content, new JGitUtil.CommitInfo(revCommit),
|
repo.html.blob(id, repository, path.split("/").toList, content, new JGitUtil.CommitInfo(revCommit),
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ trait WikiService {
|
|||||||
message
|
message
|
||||||
})
|
})
|
||||||
|
|
||||||
Some(newHeadId)
|
Some(newHeadId.getName)
|
||||||
} else None
|
} else None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,8 +92,9 @@ object JGitUtil {
|
|||||||
*
|
*
|
||||||
* @param viewType "image", "large" or "other"
|
* @param viewType "image", "large" or "other"
|
||||||
* @param content the string content
|
* @param content the string content
|
||||||
|
* @param charset the character encoding
|
||||||
*/
|
*/
|
||||||
case class ContentInfo(viewType: String, content: Option[String])
|
case class ContentInfo(viewType: String, content: Option[String], charset: Option[String])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The tag data.
|
* The tag data.
|
||||||
@@ -480,7 +481,7 @@ object JGitUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def createNewCommit(git: Git, inserter: ObjectInserter, headId: AnyObjectId, treeId: AnyObjectId,
|
def createNewCommit(git: Git, inserter: ObjectInserter, headId: AnyObjectId, treeId: AnyObjectId,
|
||||||
fullName: String, mailAddress: String, message: String): String = {
|
fullName: String, mailAddress: String, message: String): ObjectId = {
|
||||||
val newCommit = new CommitBuilder()
|
val newCommit = new CommitBuilder()
|
||||||
newCommit.setCommitter(new PersonIdent(fullName, mailAddress))
|
newCommit.setCommitter(new PersonIdent(fullName, mailAddress))
|
||||||
newCommit.setAuthor(new PersonIdent(fullName, mailAddress))
|
newCommit.setAuthor(new PersonIdent(fullName, mailAddress))
|
||||||
@@ -498,7 +499,7 @@ object JGitUtil {
|
|||||||
refUpdate.setNewObjectId(newHeadId)
|
refUpdate.setNewObjectId(newHeadId)
|
||||||
refUpdate.update()
|
refUpdate.update()
|
||||||
|
|
||||||
newHeadId.getName
|
newHeadId
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -29,11 +29,6 @@
|
|||||||
<span class="muted">@datetime(latestCommit.time)</span>
|
<span class="muted">@datetime(latestCommit.time)</span>
|
||||||
<a href="@url(repository)/commit/@latestCommit.id" class="commit-message">@link(latestCommit.summary, repository)</a>
|
<a href="@url(repository)/commit/@latestCommit.id" class="commit-message">@link(latestCommit.summary, repository)</a>
|
||||||
</div>
|
</div>
|
||||||
@if(hasWritePermission){
|
|
||||||
<div class="btn-group pull-right">
|
|
||||||
<a class="btn btn-mini btn-danger" href="@url(repository)/delete/@encodeRefName(branch)/@pathList.mkString("/")">Delete</a>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
@if(hasWritePermission){
|
@if(hasWritePermission){
|
||||||
<a class="btn btn-mini" href="@url(repository)/edit/@encodeRefName(branch)/@pathList.mkString("/")">Edit</a>
|
<a class="btn btn-mini" href="@url(repository)/edit/@encodeRefName(branch)/@pathList.mkString("/")">Edit</a>
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
<div style="text-align: right;">
|
<div style="text-align: right;">
|
||||||
<a href="@url(repository)/blob/@encodeRefName(branch)/@pathList.mkString("/")" class="btn btn-danger">Cancel</a>
|
<a href="@url(repository)/blob/@encodeRefName(branch)/@pathList.mkString("/")" class="btn btn-danger">Cancel</a>
|
||||||
<input type="submit" id="commit" class="btn btn-success" value="Commit changes"/>
|
<input type="submit" id="commit" class="btn btn-success" value="Commit changes"/>
|
||||||
|
<input type="hidden" id="charset" name="charset" value="@content.charset"/>
|
||||||
<input type="hidden" id="content" name="content" value=""/>
|
<input type="hidden" id="content" name="content" value=""/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user