mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-02 11:36:05 +01:00
(refs #38)Add reverting wiki from history.
This commit is contained in:
@@ -6,12 +6,14 @@ import util.Directory._
|
||||
import util.ControlUtil._
|
||||
import jp.sf.amateras.scalatra.forms._
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.eclipse.jgit.api.errors.PatchApplyException
|
||||
import org.scalatra.FlashMapSupport
|
||||
|
||||
class WikiController extends WikiControllerBase
|
||||
with WikiService with RepositoryService with AccountService with ActivityService
|
||||
with CollaboratorsAuthenticator with ReferrerAuthenticator
|
||||
|
||||
trait WikiControllerBase extends ControllerBase {
|
||||
trait WikiControllerBase extends ControllerBase with FlashMapSupport {
|
||||
self: WikiService with RepositoryService with ActivityService
|
||||
with CollaboratorsAuthenticator with ReferrerAuthenticator =>
|
||||
|
||||
@@ -58,18 +60,45 @@ trait WikiControllerBase extends ControllerBase {
|
||||
|
||||
get("/:owner/:repository/wiki/:page/_compare/:commitId")(referrersOnly { repository =>
|
||||
val pageName = StringUtil.urlDecode(params("page"))
|
||||
val commitId = params("commitId").split("\\.\\.\\.")
|
||||
|
||||
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
|
||||
wiki.html.compare(Some(pageName), JGitUtil.getDiffs(git, commitId(0), commitId(1), true), repository)
|
||||
defining(params("commitId").split("\\.\\.\\.")){ case Array(from, to) =>
|
||||
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
|
||||
wiki.html.compare(Some(pageName), from, to, JGitUtil.getDiffs(git, from, to, true), repository,
|
||||
hasWritePermission(repository.owner, repository.name, context.loginAccount), flash.get("info"))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/_compare/:commitId")(referrersOnly { repository =>
|
||||
val commitId = params("commitId").split("\\.\\.\\.")
|
||||
defining(params("commitId").split("\\.\\.\\.")){ case Array(from, to) =>
|
||||
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
|
||||
wiki.html.compare(None, from, to, JGitUtil.getDiffs(git, from, to, true), repository,
|
||||
hasWritePermission(repository.owner, repository.name, context.loginAccount), flash.get("info"))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
|
||||
wiki.html.compare(None, JGitUtil.getDiffs(git, commitId(0), commitId(1), true), repository)
|
||||
get("/:owner/:repository/wiki/:page/_revert/:commitId")(collaboratorsOnly { repository =>
|
||||
val pageName = StringUtil.urlDecode(params("page"))
|
||||
|
||||
defining(params("commitId").split("\\.\\.\\.")){ case Array(from, to) =>
|
||||
if(revertWikiPage(repository.owner, repository.name, from, to, context.loginAccount.get, Some(pageName))){
|
||||
redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}")
|
||||
} else {
|
||||
flash += "info" -> "This patch was not able to be reversed."
|
||||
redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_compare/${from}...${to}")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/_revert/:commitId")(collaboratorsOnly { repository =>
|
||||
defining(params("commitId").split("\\.\\.\\.")){ case Array(from, to) =>
|
||||
if(revertWikiPage(repository.owner, repository.name, from, to, context.loginAccount.get, None)){
|
||||
redirect(s"/${repository.owner}/${repository.name}/wiki/}")
|
||||
} else {
|
||||
flash += "info" -> "This patch was not able to be reversed."
|
||||
redirect(s"/${repository.owner}/${repository.name}/wiki/_compare/${from}...${to}")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -4,8 +4,11 @@ import java.io.File
|
||||
import java.util.Date
|
||||
import org.eclipse.jgit.api.Git
|
||||
import org.apache.commons.io.FileUtils
|
||||
import util.{Directory, JGitUtil, LockUtil}
|
||||
import util.{StringUtil, Directory, JGitUtil, LockUtil}
|
||||
import util.ControlUtil._
|
||||
import org.eclipse.jgit.treewalk.CanonicalTreeParser
|
||||
import org.eclipse.jgit.diff.DiffFormatter
|
||||
import org.eclipse.jgit.api.errors.PatchApplyException
|
||||
|
||||
object WikiService {
|
||||
|
||||
@@ -90,6 +93,52 @@ trait WikiService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverts specified changes.
|
||||
*/
|
||||
def revertWikiPage(owner: String, repository: String, from: String, to: String,
|
||||
committer: model.Account, pageName: Option[String]): Boolean = {
|
||||
LockUtil.lock(s"${owner}/${repository}/wiki"){
|
||||
using(Git.open(Directory.getWikiWorkDir(owner, repository))){ git =>
|
||||
val reader = git.getRepository.newObjectReader
|
||||
val oldTreeIter = new CanonicalTreeParser
|
||||
oldTreeIter.reset(reader, git.getRepository.resolve(from + "^{tree}"))
|
||||
|
||||
val newTreeIter = new CanonicalTreeParser
|
||||
newTreeIter.reset(reader, git.getRepository.resolve(to + "^{tree}"))
|
||||
|
||||
import scala.collection.JavaConverters._
|
||||
val diffs = git.diff.setNewTree(oldTreeIter).setOldTree(newTreeIter).call.asScala.filter { diff =>
|
||||
pageName match {
|
||||
case Some(x) => diff.getNewPath == x + ".md"
|
||||
case None => true
|
||||
}
|
||||
}
|
||||
|
||||
val patch = using(new java.io.ByteArrayOutputStream()){ out =>
|
||||
val formatter = new DiffFormatter(out)
|
||||
formatter.setRepository(git.getRepository)
|
||||
formatter.format(diffs.asJava)
|
||||
new String(out.toByteArray, "UTF-8")
|
||||
}
|
||||
|
||||
try {
|
||||
git.apply.setPatch(new java.io.ByteArrayInputStream(patch.getBytes("UTF-8"))).call
|
||||
git.add.addFilepattern(".").call
|
||||
git.commit.setCommitter(committer.userName, committer.mailAddress).setMessage(pageName match {
|
||||
case Some(x) => s"Revert ${from} ... ${to} on ${x}"
|
||||
case None => s"Revert ${from} ... ${to}"
|
||||
}).call
|
||||
git.push.call
|
||||
true
|
||||
} catch {
|
||||
case ex: PatchApplyException => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save the wiki page.
|
||||
*/
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
@(pageName: Option[String],
|
||||
from: String,
|
||||
to: String,
|
||||
diffs: Seq[util.JGitUtil.DiffInfo],
|
||||
repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context)
|
||||
repository: service.RepositoryService.RepositoryInfo,
|
||||
hasWritePermission: Boolean,
|
||||
info: Option[Any])(implicit context: app.Context)
|
||||
@import context._
|
||||
@import view.helpers._
|
||||
@import org.eclipse.jgit.diff.DiffEntry.ChangeType
|
||||
@html.main(s"Compare Revisions - ${repository.owner}/${repository.name}", Some(repository)){
|
||||
@helper.html.information(info)
|
||||
@html.header("wiki", repository)
|
||||
@tab("history", repository)
|
||||
<ul class="nav nav-tabs">
|
||||
@@ -23,4 +28,13 @@
|
||||
</li>
|
||||
</ul>
|
||||
@helper.html.diff(diffs, repository, None, None, false)
|
||||
@if(hasWritePermission){
|
||||
<div>
|
||||
@if(pageName.isDefined){
|
||||
<a href="@url(repository)/wiki/@urlEncode(pageName)/_revert/@from...@to" class="btn">Revert Changes</a>
|
||||
} else {
|
||||
<a href="@url(repository)/wiki/_revert/@from...@to" class="btn">Revert Changes</a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user