Add --path parameter to GetPatch
Adds path parameter to GetPatch.java for fetching a diff of a specific file. Also includes a unit test for the path parameter. Feature: Issue 4669 Change-Id: Id211fff3b6d9ba6ae16835253f2d328ccf7b5020
This commit is contained in:
@@ -3477,6 +3477,9 @@ Query parameter `download` (e.g. `/changes/.../patch?download`)
|
||||
will suggest the browser save the patch as `commitsha1.diff.base64`,
|
||||
for later processing by command line tools.
|
||||
|
||||
If the `path` parameter is set, the returned content is a diff of the single
|
||||
file that the path refers to.
|
||||
|
||||
[[submit-preview]]
|
||||
=== Submit Preview
|
||||
--
|
||||
|
@@ -52,15 +52,7 @@ public class PushOneCommit {
|
||||
public static final String SUBJECT = "test commit";
|
||||
public static final String FILE_NAME = "a.txt";
|
||||
public static final String FILE_CONTENT = "some content";
|
||||
public static final String PATCH =
|
||||
"From %s Mon Sep 17 00:00:00 2001\n" +
|
||||
"From: Administrator <admin@example.com>\n" +
|
||||
"Date: %s\n" +
|
||||
"Subject: [PATCH] test commit\n" +
|
||||
"\n" +
|
||||
"Change-Id: %s\n" +
|
||||
"---\n" +
|
||||
"\n" +
|
||||
public static final String PATCH_FILE_ONLY =
|
||||
"diff --git a/a.txt b/a.txt\n" +
|
||||
"new file mode 100644\n" +
|
||||
"index 0000000..f0eec86\n" +
|
||||
@@ -69,6 +61,15 @@ public class PushOneCommit {
|
||||
"@@ -0,0 +1 @@\n" +
|
||||
"+some content\n" +
|
||||
"\\ No newline at end of file\n";
|
||||
public static final String PATCH =
|
||||
"From %s Mon Sep 17 00:00:00 2001\n" +
|
||||
"From: Administrator <admin@example.com>\n" +
|
||||
"Date: %s\n" +
|
||||
"Subject: [PATCH] test commit\n" +
|
||||
"\n" +
|
||||
"Change-Id: %s\n" +
|
||||
"---\n" +
|
||||
"\n" + PATCH_FILE_ONLY;
|
||||
|
||||
public interface Factory {
|
||||
PushOneCommit create(
|
||||
|
@@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.gerrit.acceptance.PushOneCommit.FILE_CONTENT;
|
||||
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
|
||||
import static com.google.gerrit.acceptance.PushOneCommit.PATCH;
|
||||
import static com.google.gerrit.acceptance.PushOneCommit.PATCH_FILE_ONLY;
|
||||
import static com.google.gerrit.acceptance.PushOneCommit.SUBJECT;
|
||||
import static com.google.gerrit.reviewdb.client.Patch.COMMIT_MSG;
|
||||
import static com.google.gerrit.reviewdb.client.Patch.MERGE_LIST;
|
||||
@@ -58,6 +59,7 @@ import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||
import com.google.gerrit.extensions.restapi.BinaryResult;
|
||||
import com.google.gerrit.extensions.restapi.ETagView;
|
||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||
import com.google.gerrit.reviewdb.client.Branch;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||
@@ -922,6 +924,24 @@ public class RevisionIT extends AbstractDaemonTest {
|
||||
String.format(PATCH, r.getCommit().name(), date, r.getChangeId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchWithPath() throws Exception {
|
||||
PushOneCommit.Result r = createChange();
|
||||
ChangeApi changeApi = gApi.changes()
|
||||
.id(r.getChangeId());
|
||||
BinaryResult bin = changeApi
|
||||
.revision(r.getCommit().name())
|
||||
.patch(FILE_NAME);
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
bin.writeTo(os);
|
||||
String res = new String(os.toByteArray(), UTF_8);
|
||||
assertThat(res).isEqualTo(PATCH_FILE_ONLY);
|
||||
|
||||
exception.expect(ResourceNotFoundException.class);
|
||||
exception.expectMessage("File not found: nonexistent-file.");
|
||||
changeApi.revision(r.getCommit().name()).patch("nonexistent-file");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actions() throws Exception {
|
||||
PushOneCommit.Result r = createChange();
|
||||
|
@@ -72,6 +72,7 @@ public interface RevisionApi {
|
||||
* Returns patch of revision.
|
||||
*/
|
||||
BinaryResult patch() throws RestApiException;
|
||||
BinaryResult patch(String path) throws RestApiException;
|
||||
|
||||
Map<String, ActionInfo> actions() throws RestApiException;
|
||||
|
||||
@@ -252,6 +253,11 @@ public interface RevisionApi {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryResult patch(String path) throws RestApiException {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ActionInfo> actions() throws RestApiException {
|
||||
throw new NotImplementedException();
|
||||
|
@@ -462,6 +462,15 @@ class RevisionApiImpl implements RevisionApi {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryResult patch(String path) throws RestApiException {
|
||||
try {
|
||||
return getPatch.setPath(path).apply(revision);
|
||||
} catch (IOException e) {
|
||||
throw new RestApiException("Cannot get patch", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ActionInfo> actions() throws RestApiException {
|
||||
return revisionActions.apply(revision).value();
|
||||
|
@@ -18,6 +18,7 @@ import static java.nio.charset.StandardCharsets.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.git.GitRepositoryManager;
|
||||
@@ -30,6 +31,7 @@ import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||
import org.kohsuke.args4j.Option;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -43,20 +45,25 @@ import java.util.zip.ZipOutputStream;
|
||||
public class GetPatch implements RestReadView<RevisionResource> {
|
||||
private final GitRepositoryManager repoManager;
|
||||
|
||||
private final String FILE_NOT_FOUND = "File not found: %s.";
|
||||
|
||||
@Option(name = "--zip")
|
||||
private boolean zip;
|
||||
|
||||
@Option(name = "--download")
|
||||
private boolean download;
|
||||
|
||||
@Option(name = "--path")
|
||||
private String path;
|
||||
|
||||
@Inject
|
||||
GetPatch(GitRepositoryManager repoManager) {
|
||||
this.repoManager = repoManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryResult apply(RevisionResource rsrc)
|
||||
throws ResourceConflictException, IOException {
|
||||
public BinaryResult apply(RevisionResource rsrc) throws
|
||||
ResourceConflictException, IOException, ResourceNotFoundException {
|
||||
Project.NameKey project = rsrc.getControl().getProject().getNameKey();
|
||||
final Repository repo = repoManager.openRepository(project);
|
||||
boolean close = true;
|
||||
@@ -93,9 +100,15 @@ public class GetPatch implements RestReadView<RevisionResource> {
|
||||
}
|
||||
|
||||
private void format(OutputStream out) throws IOException {
|
||||
out.write(formatEmailHeader(commit).getBytes(UTF_8));
|
||||
// Only add header if no path is specified
|
||||
if (path == null) {
|
||||
out.write(formatEmailHeader(commit).getBytes(UTF_8));
|
||||
}
|
||||
try (DiffFormatter fmt = new DiffFormatter(out)) {
|
||||
fmt.setRepository(repo);
|
||||
if (path != null) {
|
||||
fmt.setPathFilter(PathFilter.create(path));
|
||||
}
|
||||
fmt.format(base.getTree(), commit.getTree());
|
||||
fmt.flush();
|
||||
}
|
||||
@@ -108,6 +121,11 @@ public class GetPatch implements RestReadView<RevisionResource> {
|
||||
}
|
||||
};
|
||||
|
||||
if (path != null && bin.asString().isEmpty()) {
|
||||
throw new ResourceNotFoundException(
|
||||
String.format(FILE_NOT_FOUND, path));
|
||||
}
|
||||
|
||||
if (zip) {
|
||||
bin.disableGzip()
|
||||
.setContentType("application/zip")
|
||||
@@ -134,6 +152,11 @@ public class GetPatch implements RestReadView<RevisionResource> {
|
||||
}
|
||||
}
|
||||
|
||||
public GetPatch setPath(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
private static String formatEmailHeader(RevCommit commit) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
PersonIdent author = commit.getAuthorIdent();
|
||||
|
Reference in New Issue
Block a user