mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-01 19:15:59 +01:00
Added compare revisions for Wiki changes.
This commit is contained in:
@@ -45,6 +45,32 @@ class WikiController extends ControllerBase {
|
|||||||
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
|
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get("/:owner/:repository/wiki/:page/_compare/:commitId"){
|
||||||
|
val owner = params("owner")
|
||||||
|
val repository = params("repository")
|
||||||
|
val page = params("page")
|
||||||
|
val commitId = params("commitId").split("\\.\\.\\.")
|
||||||
|
|
||||||
|
println(commitId(0))
|
||||||
|
println(commitId(1))
|
||||||
|
|
||||||
|
html.wikicompare(Some(page),
|
||||||
|
WikiUtil.getDiffs(Git.open(WikiUtil.getWikiRepositoryDir(owner, repository)), commitId(0), commitId(1)),
|
||||||
|
JGitUtil.getRepositoryInfo(owner, repository, servletContext))
|
||||||
|
}
|
||||||
|
|
||||||
|
get("/:owner/:repository/wiki/_compare/:commitId"){
|
||||||
|
val owner = params("owner")
|
||||||
|
val repository = params("repository")
|
||||||
|
val commitId = params("commitId").split("\\.\\.\\.")
|
||||||
|
|
||||||
|
println(commitId(0))
|
||||||
|
println(commitId(1))
|
||||||
|
|
||||||
|
html.wikicompare(None,
|
||||||
|
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"){
|
||||||
val owner = params("owner")
|
val owner = params("owner")
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ import java.util.Date
|
|||||||
import org.eclipse.jgit.api.Git
|
import org.eclipse.jgit.api.Git
|
||||||
import org.apache.commons.io.FileUtils
|
import org.apache.commons.io.FileUtils
|
||||||
import org.eclipse.jgit.lib.RepositoryBuilder
|
import org.eclipse.jgit.lib.RepositoryBuilder
|
||||||
|
import app.DiffInfo
|
||||||
|
import org.eclipse.jgit.treewalk.CanonicalTreeParser
|
||||||
|
import org.eclipse.jgit.revwalk.RevCommit
|
||||||
|
import org.eclipse.jgit.treewalk.TreeWalk
|
||||||
|
import org.eclipse.jgit.revwalk.RevWalk
|
||||||
|
import org.eclipse.jgit.diff.DiffEntry.ChangeType
|
||||||
|
|
||||||
object WikiUtil {
|
object WikiUtil {
|
||||||
|
|
||||||
@@ -121,4 +127,53 @@ object WikiUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def getDiffs(git: Git, commitId1: String, commitId2: String): List[DiffInfo] = {
|
||||||
|
// @scala.annotation.tailrec
|
||||||
|
// def getCommitLog(i: java.util.Iterator[RevCommit], logs: List[RevCommit]): List[RevCommit] =
|
||||||
|
// i.hasNext match {
|
||||||
|
// case true if(logs.size < 2) => getCommitLog(i, logs :+ i.next)
|
||||||
|
// case _ => logs
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// val revWalk = new RevWalk(git.getRepository)
|
||||||
|
// revWalk.markStart(revWalk.parseCommit(git.getRepository.resolve(commitId2)))
|
||||||
|
//
|
||||||
|
// val commits = getCommitLog(revWalk.iterator, Nil)
|
||||||
|
// revWalk.release
|
||||||
|
//
|
||||||
|
// val revCommit = commits(0)
|
||||||
|
//
|
||||||
|
//// if(commits.length >= 2){
|
||||||
|
// // not initial commit
|
||||||
|
// val oldCommit = commits(1)
|
||||||
|
|
||||||
|
// get diff between specified commit and its previous commit
|
||||||
|
val reader = git.getRepository.newObjectReader
|
||||||
|
|
||||||
|
val oldTreeIter = new CanonicalTreeParser
|
||||||
|
oldTreeIter.reset(reader, git.getRepository.resolve(commitId1 + "^{tree}"))
|
||||||
|
|
||||||
|
val newTreeIter = new CanonicalTreeParser
|
||||||
|
newTreeIter.reset(reader, git.getRepository.resolve(commitId2 + "^{tree}"))
|
||||||
|
|
||||||
|
import scala.collection.JavaConverters._
|
||||||
|
git.diff.setNewTree(newTreeIter).setOldTree(oldTreeIter).call.asScala.map { diff =>
|
||||||
|
DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath,
|
||||||
|
JGitUtil.getContent(git, diff.getOldId.toObjectId, false).map(new String(_, "UTF-8")),
|
||||||
|
JGitUtil.getContent(git, diff.getNewId.toObjectId, false).map(new String(_, "UTF-8")))
|
||||||
|
}.toList
|
||||||
|
// } else {
|
||||||
|
// // initial commit
|
||||||
|
// val walk = new TreeWalk(git.getRepository)
|
||||||
|
// walk.addTree(revCommit.getTree)
|
||||||
|
// val buffer = new scala.collection.mutable.ListBuffer[DiffInfo]()
|
||||||
|
// while(walk.next){
|
||||||
|
// buffer.append(DiffInfo(ChangeType.ADD, null, walk.getPathString, None,
|
||||||
|
// JGitUtil.getContent(git, walk.getObjectId(0), false).map(new String(_, "UTF-8"))))
|
||||||
|
// }
|
||||||
|
// walk.release
|
||||||
|
// buffer.toList
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -21,95 +21,5 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@diff(diffs, repository, Some(commit.id))
|
||||||
@diffs.zipWithIndex.map { case (diff, i) =>
|
|
||||||
<table class="table table-bordered">
|
|
||||||
<tr>
|
|
||||||
<th style="font-weight: normal;">
|
|
||||||
@if(diff.changeType == ChangeType.COPY || diff.changeType == ChangeType.RENAME){
|
|
||||||
@diff.oldPath -> @diff.newPath
|
|
||||||
}
|
|
||||||
@if(diff.changeType == ChangeType.ADD || diff.changeType == ChangeType.DELETE || diff.changeType == ChangeType.MODIFY){
|
|
||||||
@diff.newPath
|
|
||||||
}
|
|
||||||
<div class="pull-right align-right">
|
|
||||||
<a href="@path/@repository.owner/@repository.name/blob/@commit.id/@diff.newPath" class="btn btn-small">View file @@ @commit.id.substring(0, 10)</a>
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
@if(diff.newContent != None || diff.oldContent != None){
|
|
||||||
<div id="diff-@i"></div>
|
|
||||||
<textarea id="newText-@i" style="display: none;">@diff.newContent.getOrElse("")</textarea>
|
|
||||||
<textarea id="oldText-@i" style="display: none;">@diff.oldContent.getOrElse("")</textarea>
|
|
||||||
} else {
|
|
||||||
Too big file not shown
|
|
||||||
}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
<script type="text/javascript" src="@path/assets/jsdifflib/difflib.js"></script>
|
|
||||||
<script type="text/javascript" src="@path/assets/jsdifflib/diffview.js"></script>
|
|
||||||
<link href="@path/assets/jsdifflib/diffview.css" type="text/css" rel="stylesheet" />
|
|
||||||
<style type="text/css">
|
|
||||||
table.inlinediff {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.inlinediff thead {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
td.insert, td.equal, td.delete {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
|
||||||
function diffUsingJS(oldTextId, newTextId, outputId) {
|
|
||||||
// get the baseText and newText values from the two textboxes, and split them into lines
|
|
||||||
var oldText = document.getElementById(oldTextId).value;
|
|
||||||
if(oldText == ''){
|
|
||||||
var oldLines = [];
|
|
||||||
} else {
|
|
||||||
var oldLines = difflib.stringAsLines(oldText);
|
|
||||||
}
|
|
||||||
|
|
||||||
var newText = document.getElementById(newTextId).value
|
|
||||||
if(newText == ''){
|
|
||||||
var newLines = [];
|
|
||||||
} else {
|
|
||||||
var newLines = difflib.stringAsLines(newText);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a SequenceMatcher instance that diffs the two sets of lines
|
|
||||||
var sm = new difflib.SequenceMatcher(oldLines, newLines);
|
|
||||||
|
|
||||||
// get the opcodes from the SequenceMatcher instance
|
|
||||||
// opcodes is a list of 3-tuples describing what changes should be made to the base text
|
|
||||||
// in order to yield the new text
|
|
||||||
var opcodes = sm.get_opcodes();
|
|
||||||
var diffoutputdiv = document.getElementById(outputId);
|
|
||||||
while (diffoutputdiv.firstChild) diffoutputdiv.removeChild(diffoutputdiv.firstChild);
|
|
||||||
|
|
||||||
// build the diff view and add it to the current DOM
|
|
||||||
diffoutputdiv.appendChild(diffview.buildView({
|
|
||||||
baseTextLines: oldLines,
|
|
||||||
newTextLines: newLines,
|
|
||||||
opcodes: opcodes,
|
|
||||||
contextSize: 4,
|
|
||||||
viewType: 1
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
$(function(){
|
|
||||||
@diffs.zipWithIndex.map { case (diff, i) =>
|
|
||||||
@if(diff.newContent != None || diff.oldContent != None){
|
|
||||||
diffUsingJS('oldText-@i', 'newText-@i', 'diff-@i');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
94
src/main/twirl/diff.scala.html
Normal file
94
src/main/twirl/diff.scala.html
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
@(diffs: Seq[app.DiffInfo], repository: app.RepositoryInfo, commitId: Option[String])(implicit context: app.Context)
|
||||||
|
@import context._
|
||||||
|
@import org.eclipse.jgit.diff.DiffEntry.ChangeType
|
||||||
|
@diffs.zipWithIndex.map { case (diff, i) =>
|
||||||
|
<table class="table table-bordered">
|
||||||
|
<tr>
|
||||||
|
<th style="font-weight: normal;">
|
||||||
|
@if(diff.changeType == ChangeType.COPY || diff.changeType == ChangeType.RENAME){
|
||||||
|
@diff.oldPath -> @diff.newPath
|
||||||
|
}
|
||||||
|
@if(diff.changeType == ChangeType.ADD || diff.changeType == ChangeType.DELETE || diff.changeType == ChangeType.MODIFY){
|
||||||
|
@diff.newPath
|
||||||
|
}
|
||||||
|
@if(commitId.isDefined){
|
||||||
|
<div class="pull-right align-right">
|
||||||
|
<a href="@path/@repository.owner/@repository.name/blob/@commitId.get/@diff.newPath" class="btn btn-small">View file @@ @commitId.get.substring(0, 10)</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
@if(diff.newContent != None || diff.oldContent != None){
|
||||||
|
<div id="diff-@i"></div>
|
||||||
|
<textarea id="newText-@i" style="display: none;">@diff.newContent.getOrElse("")</textarea>
|
||||||
|
<textarea id="oldText-@i" style="display: none;">@diff.oldContent.getOrElse("")</textarea>
|
||||||
|
} else {
|
||||||
|
Too big file not shown
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
}
|
||||||
|
<script type="text/javascript" src="@path/assets/jsdifflib/difflib.js"></script>
|
||||||
|
<script type="text/javascript" src="@path/assets/jsdifflib/diffview.js"></script>
|
||||||
|
<link href="@path/assets/jsdifflib/diffview.css" type="text/css" rel="stylesheet" />
|
||||||
|
<style type="text/css">
|
||||||
|
table.inlinediff {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.inlinediff thead {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.insert, td.equal, td.delete {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
function diffUsingJS(oldTextId, newTextId, outputId) {
|
||||||
|
// get the baseText and newText values from the two textboxes, and split them into lines
|
||||||
|
var oldText = document.getElementById(oldTextId).value;
|
||||||
|
if(oldText == ''){
|
||||||
|
var oldLines = [];
|
||||||
|
} else {
|
||||||
|
var oldLines = difflib.stringAsLines(oldText);
|
||||||
|
}
|
||||||
|
|
||||||
|
var newText = document.getElementById(newTextId).value
|
||||||
|
if(newText == ''){
|
||||||
|
var newLines = [];
|
||||||
|
} else {
|
||||||
|
var newLines = difflib.stringAsLines(newText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a SequenceMatcher instance that diffs the two sets of lines
|
||||||
|
var sm = new difflib.SequenceMatcher(oldLines, newLines);
|
||||||
|
|
||||||
|
// get the opcodes from the SequenceMatcher instance
|
||||||
|
// opcodes is a list of 3-tuples describing what changes should be made to the base text
|
||||||
|
// in order to yield the new text
|
||||||
|
var opcodes = sm.get_opcodes();
|
||||||
|
var diffoutputdiv = document.getElementById(outputId);
|
||||||
|
while (diffoutputdiv.firstChild) diffoutputdiv.removeChild(diffoutputdiv.firstChild);
|
||||||
|
|
||||||
|
// build the diff view and add it to the current DOM
|
||||||
|
diffoutputdiv.appendChild(diffview.buildView({
|
||||||
|
baseTextLines: oldLines,
|
||||||
|
newTextLines: newLines,
|
||||||
|
opcodes: opcodes,
|
||||||
|
contextSize: 4,
|
||||||
|
viewType: 1
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
@diffs.zipWithIndex.map { case (diff, i) =>
|
||||||
|
@if(diff.newContent != None || diff.oldContent != None){
|
||||||
|
diffUsingJS('oldText-@i', 'newText-@i', 'diff-@i');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
@(branch: String, repository: app.RepositoryInfo, pathList: List[String], latestCommit: app.CommitInfo, files: List[app.FileInfo], readme: Option[String])(implicit context: app.Context)
|
@(branch: String, repository: app.RepositoryInfo, pathList: List[String], latestCommit: app.CommitInfo, files: List[app.FileInfo], readme: Option[String])(implicit context: app.Context)
|
||||||
@import context._
|
@import context._
|
||||||
@import view.helpers
|
@import view.helpers
|
||||||
@main(repository.owner+"/"+repository.name) {
|
@main(repository.owner + "/" + repository.name) {
|
||||||
@header("code", repository)
|
@header("code", repository)
|
||||||
@navtab(branch, repository, "files")
|
@navtab(branch, repository, "files")
|
||||||
<div class="head">
|
<div class="head">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>@title - GitBucket</title>
|
<title>@title</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<!-- Le styles -->
|
<!-- Le styles -->
|
||||||
<link href="@path/assets/bootstrap/css/bootstrap.css" rel="stylesheet">
|
<link href="@path/assets/bootstrap/css/bootstrap.css" rel="stylesheet">
|
||||||
|
|||||||
24
src/main/twirl/wikicompare.scala.html
Normal file
24
src/main/twirl/wikicompare.scala.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
@(pageName: Option[String], diffs: Seq[app.DiffInfo], repository: app.RepositoryInfo)(implicit context: app.Context)
|
||||||
|
@import view.helpers
|
||||||
|
@import context._
|
||||||
|
@import org.eclipse.jgit.diff.DiffEntry.ChangeType
|
||||||
|
@main("Compare Revisions - " + repository.owner + "/" + repository.name){
|
||||||
|
@header("wiki", repository)
|
||||||
|
@wikitab("history", repository)
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
<li>
|
||||||
|
<h1 class="wiki-title"><span class="description">Compare Revisions</span></h1>
|
||||||
|
</li>
|
||||||
|
<li class="pull-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
@if(pageName.isDefined){
|
||||||
|
<a class="btn" href="@path/@repository.owner/@repository.name/wiki/@pageName">View Page</a>
|
||||||
|
<a class="btn" href="@path/@repository.owner/@repository.name/wiki/@pageName/_history">Back to Page History</a>
|
||||||
|
} else {
|
||||||
|
<a class="btn" href="@path/@repository.owner/@repository.name/wiki/_history">Back to Wiki History</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
@diff(diffs, repository, None)
|
||||||
|
}
|
||||||
@@ -7,11 +7,10 @@
|
|||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li>
|
<li>
|
||||||
<h1 class="wiki-title">
|
<h1 class="wiki-title">
|
||||||
@if(pageName.nonEmpty){
|
|
||||||
<span class="description">History for</span> @pageName.get
|
|
||||||
}
|
|
||||||
@if(pageName.isEmpty){
|
@if(pageName.isEmpty){
|
||||||
<span class="description">History</span>
|
<span class="description">History</span>
|
||||||
|
} else {
|
||||||
|
<span class="description">History for</span> @pageName.get
|
||||||
}
|
}
|
||||||
</h1>
|
</h1>
|
||||||
</li>
|
</li>
|
||||||
@@ -33,13 +32,30 @@
|
|||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
</table>
|
</table>
|
||||||
<input type="button" value="Compare Revisions" class="btn"/>
|
<input type="button" id="compare" value="Compare Revisions" class="btn"/>
|
||||||
<input type="button" value="Back to Top" class="btn"/>
|
<input type="button" id="top" value="Back to Top" class="btn"/>
|
||||||
<script>
|
<script>
|
||||||
$(function(){
|
$(function(){
|
||||||
$('input[name=commitId]').click(function(){
|
$('input[name=commitId]').click(function(){
|
||||||
return !($('input[name=commitId]:checked').length == 3);
|
return !($('input[name=commitId]:checked').length == 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#compare').click(function(){
|
||||||
|
var e = $('input[name=commitId]:checked');
|
||||||
|
if(e.length == 2){
|
||||||
|
@if(pageName.isEmpty){
|
||||||
|
location.href = '@path/@repository.owner/@repository.name/wiki/_compare/' +
|
||||||
|
$(e.get(1)).attr('value') + '...' + $(e.get(0)).attr('value');
|
||||||
|
} else {
|
||||||
|
location.href = '@path/@repository.owner/@repository.name/wiki/@pageName.get/_compare/' +
|
||||||
|
$(e.get(1)).attr('value') + '...' + $(e.get(0)).attr('value');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#top').click(function(){
|
||||||
|
$('html,body').animate({ scrollTop: 0 }, 'fast');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user