Add links to path view from file diff headers
Change-Id: I4e71dce2db6392739bd8713ccdf819f44de33ad1
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/DiffServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/DiffServlet.java
index 2a18afb..bf90bf7 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/DiffServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/DiffServlet.java
@@ -104,7 +104,7 @@
OutputStream out = res.getOutputStream();
try {
out.write(html[0].getBytes(Charsets.UTF_8));
- formatHtmlDiff(out, repo, oldTree, newTree, view.getPathPart());
+ formatHtmlDiff(out, view, repo, oldTree, newTree, view.getPathPart());
out.write(html[1].getBytes(Charsets.UTF_8));
} finally {
out.close();
@@ -138,11 +138,11 @@
return new String[] {html.substring(0, lt), html.substring(gt + 1)};
}
- private void formatHtmlDiff(OutputStream out,
+ private void formatHtmlDiff(OutputStream out, GitilesView view,
Repository repo, AbstractTreeIterator oldTree,
AbstractTreeIterator newTree, String path)
throws IOException {
- DiffFormatter diff = new HtmlDiffFormatter(renderer, out);
+ DiffFormatter diff = new HtmlDiffFormatter(renderer, view, out);
try {
if (!path.equals("")) {
diff.setPathFilter(PathFilter.create(path));
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/HtmlDiffFormatter.java b/gitiles-servlet/src/main/java/com/google/gitiles/HtmlDiffFormatter.java
index 993197d..98a8be3 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/HtmlDiffFormatter.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/HtmlDiffFormatter.java
@@ -15,12 +15,15 @@
package com.google.gitiles;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.eclipse.jgit.util.QuotedString.GIT_PATH;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringEscapeUtils;
import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.patch.FileHeader;
@@ -30,6 +33,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
+import java.util.Map;
/** Formats a unified format patch as UTF-8 encoded HTML. */
final class HtmlDiffFormatter extends DiffFormatter {
@@ -45,17 +49,21 @@
private static final byte[] LINE_END = "</span>\n".getBytes(Charsets.UTF_8);
private final Renderer renderer;
+ private final GitilesView view;
private int fileIndex;
+ private DiffEntry entry;
- HtmlDiffFormatter(Renderer renderer, OutputStream out) {
+ HtmlDiffFormatter(Renderer renderer, GitilesView view, OutputStream out) {
super(out);
this.renderer = checkNotNull(renderer, "renderer");
+ this.view = checkNotNull(view, "view");
}
@Override
public void format(List<? extends DiffEntry> entries) throws IOException {
for (fileIndex = 0; fileIndex < entries.size(); fileIndex++) {
- format(entries.get(fileIndex));
+ entry = entries.get(fileIndex);
+ format(entry);
}
}
@@ -79,21 +87,43 @@
private void renderHeader(String header)
throws IOException {
int lf = header.indexOf('\n');
- String first;
- String rest;
- if (0 <= lf) {
- first = header.substring(0, lf);
- rest = header.substring(lf + 1);
+ String rest = 0 <= lf ? header.substring(lf + 1) : "";
+
+ // Based on DiffFormatter.formatGitDiffFirstHeaderLine.
+ List<Map<String, String>> parts = Lists.newArrayListWithCapacity(3);
+ parts.add(ImmutableMap.of("text", "diff --git"));
+ if (entry.getChangeType() != ChangeType.ADD) {
+ parts.add(ImmutableMap.of(
+ "text", GIT_PATH.quote(getOldPrefix() + entry.getOldPath()),
+ "url", revisionUrl(view.getOldRevision(), entry.getOldPath())));
} else {
- first = header;
- rest = "";
+ parts.add(ImmutableMap.of(
+ "text", GIT_PATH.quote(getOldPrefix() + entry.getNewPath())));
}
+ if (entry.getChangeType() != ChangeType.DELETE) {
+ parts.add(ImmutableMap.of(
+ "text", GIT_PATH.quote(getNewPrefix() + entry.getNewPath()),
+ "url", revisionUrl(view.getRevision(), entry.getNewPath())));
+ } else {
+ parts.add(ImmutableMap.of(
+ "text", GIT_PATH.quote(getNewPrefix() + entry.getOldPath())));
+ }
+
getOutputStream().write(renderer.newRenderer("gitiles.diffHeader")
- .setData(ImmutableMap.of("first", first, "rest", rest, "fileIndex", fileIndex))
+ .setData(ImmutableMap.of("firstParts", parts, "rest", rest, "fileIndex", fileIndex))
.render()
.getBytes(Charsets.UTF_8));
}
+ private String revisionUrl(Revision rev, String path) {
+ return GitilesView.path()
+ .copyFrom(view)
+ .setOldRevision(Revision.NULL)
+ .setRevision(Revision.named(rev.getId().name()))
+ .setPathPart(path)
+ .toUrl();
+ }
+
@Override
protected void writeHunkHeader(int aStartLine, int aEndLine,
int bStartLine, int bEndLine) throws IOException {
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/DiffDetail.soy b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/DiffDetail.soy
index d888d0a..5222fa0 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/DiffDetail.soy
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/DiffDetail.soy
@@ -38,13 +38,22 @@
/**
* File header for a single unified diff patch.
*
- * @param first the first line of the header, with no trailing LF.
+ * @param firstParts parts of the first line of the header, with "text" and
+ * optional "url" fields.
* @param rest remaining lines of the header, if any.
* @param fileIndex position of the file within the difference.
*/
{template .diffHeader}
<pre class="diff-header">
-<a name="F{$fileIndex}" class="diff-git">{$first}</a>{\n}
+<a name="F{$fileIndex}" class="diff-git"></a>
+{foreach $part in $firstParts}
+ {if not isFirst($part)}{sp}{/if}
+ {if $part.url}
+ <a href="{$part.url}">{$part.text}</a>
+ {else}
+ {$part.text}
+ {/if}
+{/foreach}{\n}
{$rest}
</pre>
{/template}