Merge "Change /patch to return base64 encoded"

This commit is contained in:
Shawn Pearce 2013-05-13 18:04:38 +00:00 committed by Gerrit Code Review
commit 4dbb2dbc71
2 changed files with 68 additions and 39 deletions

View File

@ -1459,19 +1459,17 @@ Gets the formatted patch for one revision.
GET /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/revisions/current/patch HTTP/1.0
----
The formatted patch is returned as text wrapped in JSON.
The formatted patch is returned as text encoded inside base64:
.Response
----
HTTP/1.1 200 OK
Content-Disposition: attachment
Content-Type: application/json;charset=UTF-8
Content-Type: text/plain;charset=ISO-8859-1
X-FYI-Content-Encoding: base64
X-FYI-Content-Type: application/mbox
)]}'
"From 4cf8380e526b96de9a0ad50f745028fe416c4639 Tue, 02 Apr 2013 10:26:14 +0200\nFrom: John Doe \
u003cjohn.doe@example.com\u003e\nDate: Thu, 28 Mar 2013 15:23:52 +0200\nSubject: [PATCH] Test Commit\n\n\n
diff--git a/a.txt b/a.txt\nindex bb0b141..e613f23 100644\n--- a/a.txt\n+++ b/a.txt\n@@ -1,5 +1,6 @@
\n line1\n-line2\n line3\n line4\n+line4.1\n+line4.2\n line5\n"
RnJvbSA3ZGFkY2MxNTNmZGVhMTdhYTg0ZmYzMmE2ZTI0NWRiYjY...
----
[[get-submit-type]]

View File

@ -16,11 +16,11 @@ package com.google.gerrit.server.change;
import static com.google.common.base.Charsets.UTF_8;
import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
@ -31,34 +31,31 @@ import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
public class GetPatch implements RestReadView<RevisionResource> {
private final GitRepositoryManager repoManager;
private final SimpleDateFormat df;
@Inject
GetPatch(@GerritPersonIdent final PersonIdent gerritIdent,
GitRepositoryManager repoManager) {
GetPatch(GitRepositoryManager repoManager) {
this.repoManager = repoManager;
this.df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
this.df.setCalendar(Calendar.getInstance(gerritIdent.getTimeZone(), Locale.US));
}
@Override
public String apply(RevisionResource rsrc)
public BinaryResult apply(RevisionResource rsrc)
throws ResourceNotFoundException, ResourceConflictException {
Project.NameKey project = rsrc.getControl().getProject().getNameKey();
boolean close = true;
try {
Repository repo = repoManager.openRepository(project);
final Repository repo = repoManager.openRepository(project);
try {
RevWalk rw = new RevWalk(repo);
final RevWalk rw = new RevWalk(repo);
try {
RevCommit commit =
final RevCommit commit =
rw.parseCommit(ObjectId.fromString(rsrc.getPatchSet()
.getRevision().get()));
RevCommit[] parents = commit.getParents();
@ -68,37 +65,71 @@ public class GetPatch implements RestReadView<RevisionResource> {
} else if (parents.length == 0) {
throw new ResourceConflictException("Revision has no parent.");
}
rw.parseBody(parents[0]);
final RevCommit base = parents[0];
rw.parseBody(base);
StringBuilder b = new StringBuilder();
appendHeader(b, commit);
ByteArrayOutputStream out = new ByteArrayOutputStream();
DiffFormatter f = new DiffFormatter(out);
f.setRepository(repo);
f.format(parents[0].getTree(), commit.getTree());
f.flush();
b.append(out.toString(UTF_8.name()));
return b.toString();
BinaryResult bin = new BinaryResult() {
@Override
public void writeTo(OutputStream out) throws IOException {
out.write(formatEmailHeader(commit).getBytes(UTF_8));
DiffFormatter fmt = new DiffFormatter(out);
fmt.setRepository(repo);
fmt.format(base.getTree(), commit.getTree());
fmt.flush();
}
@Override
public void close() throws IOException {
rw.release();
repo.close();
}
}.setContentType("application/mbox")
.base64();
close = false;
return bin;
} finally {
rw.release();
if (close) {
rw.release();
}
}
} finally {
repo.close();
if (close) {
repo.close();
}
}
} catch (IOException e) {
throw new ResourceNotFoundException();
}
}
private void appendHeader(StringBuilder b, RevCommit commit) {
private static String formatEmailHeader(RevCommit commit) {
StringBuilder b = new StringBuilder();
PersonIdent author = commit.getAuthorIdent();
b.append("From ").append(commit.getId().getName()).append(" ")
.append(df.format(Long.valueOf(System.currentTimeMillis()))).append("\n");
b.append("From: ").append(author.getName()).append(" <").append(author.getEmailAddress()).append(">\n");
b.append("Date: ").append(df.format(author.getWhen())).append("\n");
b.append("Subject: [PATCH] ").append(commit.getShortMessage());
String message = commit.getFullMessage().substring(
commit.getShortMessage().length());
b.append(message).append("\n\n");
String subject = commit.getShortMessage();
String msg = commit.getFullMessage().substring(subject.length());
if (msg.startsWith("\n\n")) {
msg = msg.substring(2);
}
b.append("From ").append(commit.getName())
.append(' ')
.append("Mon Sep 17 00:00:00 2001\n")
.append("From: ").append(author.getName())
.append(" <").append(author.getEmailAddress()).append(">\n")
.append("Date: ").append(formatDate(author)).append('\n')
.append("Subject: [PATCH] ").append(subject).append('\n')
.append('\n')
.append(msg);
if (!msg.endsWith("\n")) {
b.append('\n');
}
return b.append("---\n\n").toString();
}
private static String formatDate(PersonIdent author) {
SimpleDateFormat df = new SimpleDateFormat(
"EEE, dd MMM yyyy HH:mm:ss Z",
Locale.US);
df.setCalendar(Calendar.getInstance(author.getTimeZone(), Locale.US));
return df.format(author.getWhen());
}
}