diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java index 5f57d1bcc8..431e39e759 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java @@ -5,6 +5,7 @@ import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; import sonia.scm.NotFoundException; import sonia.scm.PageResult; +import sonia.scm.repository.Branch; import sonia.scm.repository.Branches; import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; @@ -26,6 +27,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import java.io.IOException; +import java.util.List; public class BranchRootResource { @@ -124,6 +126,49 @@ public class BranchRootResource { } } + @Path("{branch}/diffchangesets/{otherBranchName}") + @GET + @StatusCodes({ + @ResponseCode(code = 200, condition = "success"), + @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), + @ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the changeset"), + @ResponseCode(code = 404, condition = "not found, no changesets available in the repository"), + @ResponseCode(code = 500, condition = "internal server error") + }) + @Produces(VndMediaType.CHANGESET_COLLECTION) + @TypeHint(CollectionDto.class) + public Response changesetDiff(@PathParam("namespace") String namespace, + @PathParam("name") String name, + @PathParam("branch") String branchName, + @PathParam("otherBranchName") String otherBranchName, + @DefaultValue("0") @QueryParam("page") int page, + @DefaultValue("10") @QueryParam("pageSize") int pageSize) throws Exception { + try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { + List allBranches = repositoryService.getBranchesCommand().getBranches().getBranches(); + if (allBranches.stream().noneMatch(branch -> branchName.equals(branch.getName()))) { + throw new NotFoundException("branch", branchName); + } + if (allBranches.stream().noneMatch(branch -> otherBranchName.equals(branch.getName()))) { + throw new NotFoundException("branch", otherBranchName); + } + Repository repository = repositoryService.getRepository(); + RepositoryPermissions.read(repository).check(); + ChangesetPagingResult changesets = new PagedLogCommandBuilder(repositoryService) + .page(page) + .pageSize(pageSize) + .create() + .setBranch(branchName) + .setAncestorChangeset(otherBranchName) + .getChangesets(); + if (changesets != null && changesets.getChangesets() != null) { + PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); + return Response.ok(branchChangesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository, branchName)).build(); + } else { + return Response.ok().build(); + } + } + } + /** * Returns the branches for a repository. * diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapper.java index 7ab3ef25a8..8167e28f9a 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchToBranchDtoMapper.java @@ -28,6 +28,7 @@ public abstract class BranchToBranchDtoMapper { Links.Builder linksBuilder = linkingTo() .self(resourceLinks.branch().self(namespaceAndName, target.getName())) .single(linkBuilder("history", resourceLinks.branch().history(namespaceAndName, target.getName())).build()) + .single(linkBuilder("changesetDiff", resourceLinks.branch().changesetDiff(namespaceAndName, target.getName())).build()) .single(linkBuilder("changeset", resourceLinks.changeset().changeset(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision())).build()) .single(linkBuilder("source", resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision())).build()); target.add(linksBuilder.build()); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java index 1b397480a4..970166257a 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ResourceLinks.java @@ -322,6 +322,10 @@ class ResourceLinks { public String history(NamespaceAndName namespaceAndName, String branch) { return branchLinkBuilder.method("getRepositoryResource").parameters(namespaceAndName.getNamespace(), namespaceAndName.getName()).method("branches").parameters().method("history").parameters(branch).href(); } + + public String changesetDiff(NamespaceAndName namespaceAndName, String branch) { + return branchLinkBuilder.method("getRepositoryResource").parameters(namespaceAndName.getNamespace(), namespaceAndName.getName()).method("branches").parameters().method("changesetDiff").parameters(branch, "").href() + "{otherBranch}"; + } } public BranchCollectionLinks branchCollection() {