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}