mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-12-21 15:59:48 +01:00
Feature Partial Diff (#1581)
With this pull request, diffs for Git are loaded in chunks. This means, that for diffs with a lot of files only a part of them are loaded. In the UI a button will be displayed to load more. In the REST API, the number of files can be specified. This only works for diffs, that are delivered as "parsed" diffs. Currently, this is only available for Git. Co-authored-by: Sebastian Sdorra <sebastian.sdorra@cloudogu.com>
This commit is contained in:
@@ -36,7 +36,11 @@ import javax.inject.Inject;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
|
||||
public class GitDiffResultCommand extends AbstractGitCommand implements DiffResultCommand {
|
||||
|
||||
@@ -47,17 +51,31 @@ public class GitDiffResultCommand extends AbstractGitCommand implements DiffResu
|
||||
|
||||
public DiffResult getDiffResult(DiffCommandRequest diffCommandRequest) throws IOException {
|
||||
org.eclipse.jgit.lib.Repository repository = open();
|
||||
return new GitDiffResult(repository, Differ.diff(repository, diffCommandRequest));
|
||||
return new GitDiffResult(repository, Differ.diff(repository, diffCommandRequest), 0, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiffResult getDiffResult(DiffResultCommandRequest request) throws IOException {
|
||||
org.eclipse.jgit.lib.Repository repository = open();
|
||||
int offset = request.getOffset() == null ? 0 : request.getOffset();
|
||||
return new GitDiffResult(repository, Differ.diff(repository, request), offset, request.getLimit());
|
||||
}
|
||||
|
||||
private class GitDiffResult implements DiffResult {
|
||||
|
||||
private final org.eclipse.jgit.lib.Repository repository;
|
||||
private final Differ.Diff diff;
|
||||
private final List<DiffEntry> diffEntries;
|
||||
|
||||
private GitDiffResult(org.eclipse.jgit.lib.Repository repository, Differ.Diff diff) {
|
||||
private final int offset;
|
||||
private final Integer limit;
|
||||
|
||||
private GitDiffResult(org.eclipse.jgit.lib.Repository repository, Differ.Diff diff, int offset, Integer limit) {
|
||||
this.repository = repository;
|
||||
this.diff = diff;
|
||||
this.offset = offset;
|
||||
this.limit = limit;
|
||||
this.diffEntries = diff.getEntries();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,12 +88,32 @@ public class GitDiffResultCommand extends AbstractGitCommand implements DiffResu
|
||||
return GitUtil.getId(diff.getCommit().getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPartial() {
|
||||
return limit != null && limit + offset < diffEntries.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> getLimit() {
|
||||
return ofNullable(limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<DiffFile> iterator() {
|
||||
return diff.getEntries()
|
||||
Stream<DiffEntry> diffEntryStream = diffEntries
|
||||
.stream()
|
||||
.skip(offset);
|
||||
if (limit != null) {
|
||||
diffEntryStream = diffEntryStream.limit(limit);
|
||||
}
|
||||
return diffEntryStream
|
||||
.map(diffEntry -> new GitDiffFile(repository, diffEntry))
|
||||
.collect(Collectors.<DiffFile>toList())
|
||||
.map(DiffFile.class::cast)
|
||||
.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ public class GitDiffResultCommandTest extends AbstractGitCommandTestBase {
|
||||
DiffFile b = iterator.next();
|
||||
assertThat(b.getOldPath()).isEqualTo("b.txt");
|
||||
assertThat(b.getNewPath()).isEqualTo("/dev/null");
|
||||
|
||||
assertThat(diffResult.isPartial()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -69,6 +71,8 @@ public class GitDiffResultCommandTest extends AbstractGitCommandTestBase {
|
||||
DiffFile b = iterator.next();
|
||||
assertThat(b.getOldRevision()).isEqualTo("61780798228d17af2d34fce4cfbdf35556832472");
|
||||
assertThat(b.getNewRevision()).isEqualTo("0000000000000000000000000000000000000000");
|
||||
|
||||
assertThat(iterator.hasNext()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -119,10 +123,55 @@ public class GitDiffResultCommandTest extends AbstractGitCommandTestBase {
|
||||
assertThat(renameB.iterator().hasNext()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLimitResult() throws IOException {
|
||||
DiffResult diffResult = createDiffResult("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4", null, 1);
|
||||
Iterator<DiffFile> iterator = diffResult.iterator();
|
||||
|
||||
DiffFile a = iterator.next();
|
||||
assertThat(a.getNewPath()).isEqualTo("a.txt");
|
||||
assertThat(a.getOldPath()).isEqualTo("a.txt");
|
||||
|
||||
assertThat(iterator.hasNext()).isFalse();
|
||||
|
||||
assertThat(diffResult.isPartial()).isTrue();
|
||||
assertThat(diffResult.getLimit()).get().isEqualTo(1);
|
||||
assertThat(diffResult.getOffset()).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSetOffsetForResult() throws IOException {
|
||||
DiffResult diffResult = createDiffResult("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4", 1, null);
|
||||
Iterator<DiffFile> iterator = diffResult.iterator();
|
||||
|
||||
DiffFile b = iterator.next();
|
||||
assertThat(b.getOldPath()).isEqualTo("b.txt");
|
||||
assertThat(b.getNewPath()).isEqualTo("/dev/null");
|
||||
|
||||
assertThat(iterator.hasNext()).isFalse();
|
||||
|
||||
assertThat(diffResult.isPartial()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotBePartialWhenResultCountMatchesLimit() throws IOException {
|
||||
DiffResult diffResult = createDiffResult("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4", 0, 2);
|
||||
|
||||
assertThat(diffResult.isPartial()).isFalse();
|
||||
assertThat(diffResult.getLimit()).get().isEqualTo(2);
|
||||
assertThat(diffResult.getOffset()).isZero();
|
||||
}
|
||||
|
||||
private DiffResult createDiffResult(String s) throws IOException {
|
||||
return createDiffResult(s, null, null);
|
||||
}
|
||||
|
||||
private DiffResult createDiffResult(String s, Integer offset, Integer limit) throws IOException {
|
||||
GitDiffResultCommand gitDiffResultCommand = new GitDiffResultCommand(createContext());
|
||||
DiffCommandRequest diffCommandRequest = new DiffCommandRequest();
|
||||
DiffResultCommandRequest diffCommandRequest = new DiffResultCommandRequest();
|
||||
diffCommandRequest.setRevision(s);
|
||||
diffCommandRequest.setOffset(offset);
|
||||
diffCommandRequest.setLimit(limit);
|
||||
|
||||
return gitDiffResultCommand.getDiffResult(diffCommandRequest);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user