Browse Source

Mostly working Diff presentation.

tags/v0.5.0
James Moger 13 years ago
parent
commit
87c3d71469

+ 66
- 1
resources/gitblit.css View File

@@ -18,8 +18,9 @@ body {
padding: 0px;
}
pre.prettyprint, pre.plainprint {
pre, pre.prettyprint, pre.plainprint {
color: black;
font-family: monospace;
font-size:12px;
border:0px;
}
@@ -201,6 +202,70 @@ div.bug_hold {
text-align: center;
}
div.diff {
font-family: monospace;
}
div.diff.header {
-moz-border-bottom-colors: none;
-moz-border-image: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
background-color: #EDECE6;
border-color: #D9D8D1;
border-style: solid;
border-width: 1px 0;
font-weight: bold;
margin-top: 4px;
padding: 4px 0 2px;
}
div.diff.extended_header {
background-color: #F6F5EE;
padding: 2px 0;
font-family: inherit;
}
div.diff.add {
color: #008800;
font-family: inherit;
}
div.diff.remove {
color: #cc0000;
font-family: inherit;
}
div.diff.unchanged {
color: inherit;
font-family: inherit;
}
div.diff.hunk_header {
-moz-border-bottom-colors: none;
-moz-border-image: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
border-color: #FFE0FF;
border-style: dotted;
border-width: 1px 0 0;
margin-top: 2px;
font-family: inherit;
}
span.diff.hunk_info {
background-color: #FFEEFF;
color: #990099;
font-family: inherit;
}
span.diff.hunk_section {
color: #AA22AA;
font-family: inherit;
}
a.list {
text-decoration: none;
color: #000000;

+ 29
- 13
src/com/gitblit/tests/JGitUtilsTest.java View File

@@ -16,50 +16,50 @@ import org.eclipse.jgit.storage.file.FileRepository;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.TicGitTicket;
import com.gitblit.wicket.models.PathModel;
import com.gitblit.wicket.models.RefModel;
public class JGitUtilsTest extends TestCase {
private File repositoriesFolder = new File("c:/projects/git");
private boolean exportAll = true;
private boolean readNested = true;
private List<String> getRepositories() {
return JGitUtils.getRepositoryList(repositoriesFolder, exportAll, readNested);
}
private Repository getRepository() throws Exception {
return new FileRepository(new File(repositoriesFolder, getRepositories().get(0)) + "/" + Constants.DOT_GIT);
}
public void testFindRepositories() {
List<String> list = getRepositories();
assertTrue("No repositories found in " + repositoriesFolder, list.size() > 0);
}
public void testOpenRepository() throws Exception {
public void testOpenRepository() throws Exception {
Repository r = getRepository();
r.close();
assertTrue("Could not find repository!", r != null);
}
public void testLastChangeRepository() throws Exception {
public void testLastChangeRepository() throws Exception {
Repository r = getRepository();
Date date = JGitUtils.getLastChange(r);
r.close();
assertTrue("Could not get last repository change date!", date != null);
}
public void testRetrieveRevObject() throws Exception {
Repository r = getRepository();
RevCommit commit = JGitUtils.getCommit(r, Constants.HEAD);
RevTree tree = commit.getTree();
RevObject object = JGitUtils.getRevObject(r, tree, "AUTHORS");
RevObject object = JGitUtils.getRevObject(r, tree, "AUTHORS");
r.close();
assertTrue("Object is null!", object != null);
}
public void testRetrieveStringContent() throws Exception {
Repository r = getRepository();
RevCommit commit = JGitUtils.getCommit(r, Constants.HEAD);
@@ -69,7 +69,7 @@ public class JGitUtilsTest extends TestCase {
r.close();
assertTrue("Content is null!", content != null);
}
public void testTicGit() throws Exception {
Repository r = new FileRepository(new File(repositoriesFolder, "ticgit") + "/" + Constants.DOT_GIT);
RefModel ticgit = JGitUtils.getTicGitBranch(r);
@@ -79,4 +79,20 @@ public class JGitUtilsTest extends TestCase {
r.close();
}
public void testFilesInCommit() throws Exception {
Repository r = getRepository();
RevCommit commit = JGitUtils.getCommit(r, Constants.HEAD);
List<PathModel> paths = JGitUtils.getFilesInCommit(r, commit);
r.close();
assertTrue("No changed paths found!", paths.size() > 0);
}
public void testCommitDiff() throws Exception {
Repository r = getRepository();
RevCommit commit = JGitUtils.getCommit(r, Constants.HEAD);
String diff = JGitUtils.getCommitDiff(r, commit, false);
r.close();
System.out.println(diff);
}
}

+ 128
- 0
src/com/gitblit/utils/HtmlDiffFormatter.java View File

@@ -0,0 +1,128 @@
package com.gitblit.utils;
import static org.eclipse.jgit.lib.Constants.encodeASCII;
import java.io.IOException;
import java.io.OutputStream;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawText;
public class HtmlDiffFormatter extends DiffFormatter {
private final OutputStream os;
public HtmlDiffFormatter(OutputStream os) {
super(os);
this.os = os;
}
/**
* Output a hunk header
*
* @param aStartLine
* within first source
* @param aEndLine
* within first source
* @param bStartLine
* within second source
* @param bEndLine
* within second source
* @throws IOException
*/
@Override
protected void writeHunkHeader(int aStartLine, int aEndLine, int bStartLine, int bEndLine) throws IOException {
os.write("<div class=\"diff hunk_header\"><span class=\"diff hunk_info\">".getBytes());
os.write('@');
os.write('@');
writeRange('-', aStartLine + 1, aEndLine - aStartLine);
writeRange('+', bStartLine + 1, bEndLine - bStartLine);
os.write(' ');
os.write('@');
os.write('@');
// TODO not sure if JGit can determine hunk section
//os.write("<span class=\"diff hunk_section\">".getBytes());
//os.write("</span>".getBytes());
os.write("</span></div>".getBytes());
}
private void writeRange(final char prefix, final int begin, final int cnt) throws IOException {
os.write(' ');
os.write(prefix);
switch (cnt) {
case 0:
// If the range is empty, its beginning number must
// be the
// line just before the range, or 0 if the range is
// at the
// start of the file stream. Here, begin is always 1
// based,
// so an empty file would produce "0,0".
//
os.write(encodeASCII(begin - 1));
os.write(',');
os.write('0');
break;
case 1:
// If the range is exactly one line, produce only
// the number.
//
os.write(encodeASCII(begin));
break;
default:
os.write(encodeASCII(begin));
os.write(',');
os.write(encodeASCII(cnt));
break;
}
}
@Override
protected void writeLine(final char prefix, final RawText text, final int cur) throws IOException {
switch (prefix) {
case '+':
os.write("<div class=\"diff add\">".getBytes());
break;
case '-':
os.write("<div class=\"diff remove\">".getBytes());
break;
}
os.write(prefix);
text.writeLine(os, cur);
switch (prefix) {
case '+':
case '-':
os.write("</div>".getBytes());
break;
default:
os.write('\n');
}
}
/**
* Workaround function for complex private methods in DiffFormatter. This
* sets the html for the diff headers.
*
* @return
*/
public String getHtml() {
String html = os.toString();
String[] lines = html.split("\n");
StringBuilder sb = new StringBuilder();
sb.append("<div class=\"diff\">");
for (String line : lines) {
if (line.startsWith("diff")) {
sb.append("<div class=\"diff header\">").append(line).append("</div>");
} else if (line.startsWith("---")) {
sb.append("<div class=\"diff remove\">").append(line).append("</div>");
} else if (line.startsWith("+++")) {
sb.append("<div class=\"diff add\">").append(line).append("</div>");
} else {
sb.append(line).append('\n');
}
}
sb.append("</div>");
return sb.toString();
}
}

+ 80
- 15
src/com/gitblit/utils/JGitUtils.java View File

@@ -17,6 +17,9 @@ import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
@@ -35,6 +38,8 @@ import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.util.io.DisabledOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -243,29 +248,89 @@ public class JGitUtils {
return list;
}
public static List<PathModel> getCommitChangedPaths(Repository r, String commitId) {
public static List<PathModel> getFilesInCommit(Repository r, String commitId) {
RevCommit commit = getCommit(r, commitId);
return getCommitChangedPaths(r, commit);
return getFilesInCommit(r, commit);
}
public static List<PathModel> getCommitChangedPaths(Repository r, RevCommit commit) {
public static List<PathModel> getFilesInCommit(Repository r, RevCommit commit) {
List<PathModel> list = new ArrayList<PathModel>();
final TreeWalk walk = new TreeWalk(r);
walk.setRecursive(false);
try {
walk.addTree(commit.getTree());
while (walk.next()) {
list.add(getPathModel(walk, null, commit));
final RevWalk rw = new RevWalk(r);
RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
RevTree parentTree = parent.getTree();
RevTree commitTree = commit.getTree();
final TreeWalk walk = new TreeWalk(r);
walk.reset();
walk.setRecursive(true);
walk.addTree(parentTree);
walk.addTree(commitTree);
walk.setFilter(TreeFilter.ANY_DIFF);
RawTextComparator cmp = RawTextComparator.DEFAULT;
DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);
df.setRepository(r);
df.setDiffComparator(cmp);
df.setDetectRenames(true);
List<DiffEntry> diffs = df.scan(parentTree, commitTree);
for (DiffEntry diff : diffs) {
list.add(new PathModel(diff.getNewPath(), diff.getNewPath(), 0, diff.getNewMode().getBits(), commit.getId().getName()));
}
} catch (Throwable t) {
LOGGER.error("failed to determine files in commit!", t);
}
return list;
}
} catch (IOException e) {
LOGGER.error("Failed to get files for commit " + commit.getName(), e);
} finally {
if (walk != null) {
walk.release();
public static String getCommitDiff(Repository r, RevCommit commit, boolean outputHtml) {
return getCommitDiff(r, commit, null, outputHtml);
}
public static String getCommitDiff(Repository r, RevCommit commit, String path, boolean outputHtml) {
try {
final RevWalk rw = new RevWalk(r);
RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
RevTree parentTree = parent.getTree();
RevTree commitTree = commit.getTree();
final TreeWalk walk = new TreeWalk(r);
walk.reset();
walk.setRecursive(true);
walk.addTree(parentTree);
walk.addTree(commitTree);
if (path != null && path.trim().length() > 0) {
walk.setFilter(PathFilter.create(path));
} else {
walk.setFilter(TreeFilter.ANY_DIFF);
}
final ByteArrayOutputStream os = new ByteArrayOutputStream();
RawTextComparator cmp = RawTextComparator.DEFAULT;
DiffFormatter df;
if (outputHtml) {
df = new HtmlDiffFormatter(os);
} else {
df = new DiffFormatter(os);
}
df.setRepository(r);
df.setDiffComparator(cmp);
df.setDetectRenames(true);
List<DiffEntry> diffs = df.scan(parentTree, commitTree);
df.format(diffs);
String diff;
if (outputHtml) {
// workaround for complex private methods in DiffFormatter
diff = ((HtmlDiffFormatter) df).getHtml();
} else {
diff = os.toString();
}
df.flush();
return diff;
} catch (Throwable t) {
LOGGER.error("failed to generate commit diff!", t);
}
return list;
return null;
}
private static PathModel getPathModel(TreeWalk walk, String basePath, RevCommit commit) {
@@ -519,7 +584,7 @@ public class JGitUtils {
}
return null;
}
private static void readTicketContents(Repository r, RefModel ticgitBranch, TicGitTicket ticket) {
List<PathModel> ticketFiles = getFilesInPath(r, ticket.name, ticgitBranch.getCommit());
for (PathModel file : ticketFiles) {

+ 2
- 0
src/com/gitblit/wicket/GitBlitWebApp.java View File

@@ -31,6 +31,7 @@ import com.gitblit.wicket.models.RepositoryModel;
import com.gitblit.wicket.pages.BlobPage;
import com.gitblit.wicket.pages.BranchesPage;
import com.gitblit.wicket.pages.CommitPage;
import com.gitblit.wicket.pages.DiffPage;
import com.gitblit.wicket.pages.RepositoriesPage;
import com.gitblit.wicket.pages.ShortLogPage;
import com.gitblit.wicket.pages.SummaryPage;
@@ -69,6 +70,7 @@ public class GitBlitWebApp extends WebApplication {
mount(new MixedParamUrlCodingStrategy("/tag", TagPage.class, new String[] { "p", "h" }));
mount(new MixedParamUrlCodingStrategy("/tree", TreePage.class, new String[] { "p", "h", "f" }));
mount(new MixedParamUrlCodingStrategy("/blob", BlobPage.class, new String[] { "p", "h", "f" }));
mount(new MixedParamUrlCodingStrategy("/diff", DiffPage.class, new String[] { "p", "h", "f" }));
// setup extended urls
mount(new MixedParamUrlCodingStrategy("/ticgit", TicGitPage.class, new String[] { "p" }));

+ 1
- 1
src/com/gitblit/wicket/pages/CommitPage.java View File

@@ -76,7 +76,7 @@ public class CommitPage extends RepositoryPage {
addFullText("fullMessage", c.getFullMessage(), true);
// changed paths list
List<PathModel> paths = JGitUtils.getCommitChangedPaths(r, c);
List<PathModel> paths = JGitUtils.getFilesInCommit(r, c);
ListDataProvider<PathModel> pathsDp = new ListDataProvider<PathModel>(paths);
DataView<PathModel> pathsView = new DataView<PathModel>("changedPath", pathsDp) {
private static final long serialVersionUID = 1L;

+ 31
- 0
src/com/gitblit/wicket/pages/DiffPage.html View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<link href="prettify/prettify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="prettify/prettify.js"></script>
</head>
<body onload="prettyPrint()">
<!-- page header -->
<div wicket:id="pageHeader"></div>
<!-- page nav links -->
<div wicket:id="pageLinks"></div>
<!-- blob nav links -->
<div class="page_nav2">
<span wicket:id="historyLink"></span> | <span wicket:id="rawLink"></span> | <span wicket:id="headLink"></span>
</div>
<!-- shortlog header -->
<div class="header" wicket:id="shortlog"></div>
<!-- breadcrumbs -->
<div wicket:id="breadcrumbs"></div>
<!-- diff content -->
<pre wicket:id="diffText"></pre>
<!-- footer -->
<div wicket:id="pageFooter"></div>
</body>
</html>

+ 46
- 0
src/com/gitblit/wicket/pages/DiffPage.java View File

@@ -0,0 +1,46 @@
package com.gitblit.wicket.pages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import com.gitblit.utils.JGitUtils;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.RepositoryPage;
import com.gitblit.wicket.panels.PathBreadcrumbsPanel;
public class DiffPage extends RepositoryPage {
public DiffPage(PageParameters params) {
super(params, "diff");
final String blobPath = params.getString("f", null);
Repository r = getRepository();
RevCommit commit = JGitUtils.getCommit(r, commitId);
String diff;
if (blobPath != null && blobPath.length() > 0) {
// blob diff
diff = JGitUtils.getCommitDiff(r, commit, blobPath, true);
} else {
// commit diff
diff = JGitUtils.getCommitDiff(r, commit, true);
}
r.close();
// diff page links
add(new Label("historyLink", "history"));
add(new Label("rawLink", "raw"));
add(new Label("headLink", "HEAD"));
add(new LinkPanel("shortlog", "title", commit.getShortMessage(), CommitPage.class, newCommitParameter()));
add(new PathBreadcrumbsPanel("breadcrumbs", repositoryName, blobPath, commitId));
add(new Label("diffText", diff).setEscapeModelStrings(false));
// footer
addFooter();
}
}

+ 2
- 1
src/com/gitblit/wicket/panels/PathLinksPanel.java View File

@@ -7,6 +7,7 @@ import org.apache.wicket.markup.html.panel.Panel;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.models.PathModel;
import com.gitblit.wicket.pages.BlobPage;
import com.gitblit.wicket.pages.DiffPage;
public class PathLinksPanel extends Panel {
@@ -15,7 +16,7 @@ public class PathLinksPanel extends Panel {
public PathLinksPanel(String id, String repositoryName, PathModel path) {
super(id);
add(new Label("diff", "diff"));
add(new LinkPanel("diff", null, "diff", DiffPage.class, new PageParameters("p=" + repositoryName + ",h=" + path.commitId + ",f=" + path.path)));
add(new LinkPanel("blob", null, "view", BlobPage.class, new PageParameters("p=" + repositoryName + ",h=" + path.commitId + ",f=" + path.path)));
add(new Label("history", "history"));
}

+ 2
- 2
src/com/gitblit/wicket/panels/ShortLogLinksPanel.java View File

@@ -1,11 +1,11 @@
package com.gitblit.wicket.panels;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import com.gitblit.wicket.LinkPanel;
import com.gitblit.wicket.pages.CommitPage;
import com.gitblit.wicket.pages.DiffPage;
import com.gitblit.wicket.pages.TreePage;
@@ -17,7 +17,7 @@ public class ShortLogLinksPanel extends Panel {
super(id);
add(new LinkPanel("commit", null, "commit", CommitPage.class, new PageParameters("p=" + repositoryName + ",h=" + commitId)));
add(new Label("commitdiff", "commitdiff"));
add(new LinkPanel("commitdiff", null, "commitdiff", DiffPage.class, new PageParameters("p=" + repositoryName + ",h=" + commitId)));
add(new LinkPanel("tree", null, "tree", TreePage.class, new PageParameters("p=" + repositoryName + ",h=" + commitId)));
}
}

Loading…
Cancel
Save