diff options
author | James Moger <james.moger@gitblit.com> | 2011-04-06 09:27:14 -0400 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2011-04-06 09:27:14 -0400 |
commit | 87c3d714693b216cee9c31cdc5170715c56f541d (patch) | |
tree | aa9744ccaf2861e8aaed38edb349eed545bf34bc /src/com/gitblit/utils | |
parent | 232890f03476b8bb231d17883eb0faff93ec5049 (diff) | |
download | gitblit-87c3d714693b216cee9c31cdc5170715c56f541d.tar.gz gitblit-87c3d714693b216cee9c31cdc5170715c56f541d.zip |
Mostly working Diff presentation.
Diffstat (limited to 'src/com/gitblit/utils')
-rw-r--r-- | src/com/gitblit/utils/HtmlDiffFormatter.java | 128 | ||||
-rw-r--r-- | src/com/gitblit/utils/JGitUtils.java | 95 |
2 files changed, 208 insertions, 15 deletions
diff --git a/src/com/gitblit/utils/HtmlDiffFormatter.java b/src/com/gitblit/utils/HtmlDiffFormatter.java new file mode 100644 index 00000000..7c37862c --- /dev/null +++ b/src/com/gitblit/utils/HtmlDiffFormatter.java @@ -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();
+ }
+}
diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java index b4e0b151..1b418b08 100644 --- a/src/com/gitblit/utils/JGitUtils.java +++ b/src/com/gitblit/utils/JGitUtils.java @@ -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) {
|