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:
Kasper Nilsson
2016-10-17 15:04:33 -07:00
parent 247fa2388e
commit 81448072fb
6 changed files with 74 additions and 12 deletions

View File

@@ -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();

View File

@@ -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();