Add option to hide whitepace changes in diffs

Co-authored-by: Florian Scholdei<florian.scholdei@cloudogu.com>
Co-authored-by: René Pfeuffer<rene.pfeuffer@cloudogu.com>


Reviewed-by: Florian Scholdei <florian.scholdei@cloudogu.com>
This commit is contained in:
Viktor Egorov
2024-05-14 11:33:48 +02:00
parent e5e2fd151c
commit c8ef99cf07
37 changed files with 688 additions and 498 deletions

View File

@@ -28,8 +28,10 @@ import com.google.inject.assistedinject.Assisted;
import jakarta.inject.Inject;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.util.QuotedString;
import sonia.scm.repository.api.DiffCommandBuilder;
import sonia.scm.repository.api.IgnoreWhitespaceLevel;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
@@ -49,13 +51,16 @@ public class GitDiffCommand extends AbstractGitCommand implements DiffCommand {
@Override
public DiffCommandBuilder.OutputStreamConsumer getDiffResult(DiffCommandRequest request) throws IOException {
@SuppressWarnings("squid:S2095") // repository will be closed with the RepositoryService
org.eclipse.jgit.lib.Repository repository = open();
org.eclipse.jgit.lib.Repository repository = open();
Differ.Diff diff = Differ.diff(repository, request);
return output -> {
try (DiffFormatter formatter = new DiffFormatter(new DequoteOutputStream(output))) {
formatter.setRepository(repository);
if (request.getIgnoreWhitespaceLevel() == IgnoreWhitespaceLevel.ALL) {
formatter.setDiffComparator(RawTextComparator.WS_IGNORE_ALL);
}
for (DiffEntry e : diff.getEntries()) {
if (idOrPathChanged(e)) {

View File

@@ -26,6 +26,7 @@ package sonia.scm.repository.spi;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.lib.ObjectId;
import sonia.scm.repository.GitUtil;
import sonia.scm.repository.InternalRepositoryException;
@@ -33,6 +34,7 @@ import sonia.scm.repository.Repository;
import sonia.scm.repository.api.DiffFile;
import sonia.scm.repository.api.DiffResult;
import sonia.scm.repository.api.Hunk;
import sonia.scm.repository.api.IgnoreWhitespaceLevel;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -51,14 +53,21 @@ public class GitDiffResult implements DiffResult {
private final Differ.Diff diff;
private final List<DiffEntry> diffEntries;
private final IgnoreWhitespaceLevel ignoreWhitespaceLevel;
private final int offset;
private final Integer limit;
public GitDiffResult(Repository scmRepository, org.eclipse.jgit.lib.Repository repository, Differ.Diff diff, int offset, Integer limit) {
public GitDiffResult(Repository scmRepository,
org.eclipse.jgit.lib.Repository repository,
Differ.Diff diff,
IgnoreWhitespaceLevel ignoreWhitespaceLevel,
int offset,
Integer limit) {
this.scmRepository = scmRepository;
this.repository = repository;
this.diff = diff;
this.offset = offset;
this.ignoreWhitespaceLevel = ignoreWhitespaceLevel;
this.limit = limit;
this.diffEntries = diff.getEntries();
}
@@ -163,6 +172,9 @@ public class GitDiffResult implements DiffResult {
private String format(org.eclipse.jgit.lib.Repository repository, DiffEntry entry) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); DiffFormatter formatter = new DiffFormatter(baos)) {
if (ignoreWhitespaceLevel == IgnoreWhitespaceLevel.ALL) {
formatter.setDiffComparator(RawTextComparator.WS_IGNORE_ALL);
}
formatter.setRepository(repository);
formatter.format(entry);
return baos.toString(StandardCharsets.UTF_8);
@@ -170,6 +182,10 @@ public class GitDiffResult implements DiffResult {
throw new InternalRepositoryException(scmRepository, "failed to format diff entry", ex);
}
}
}
@Override
public IgnoreWhitespaceLevel getIgnoreWhitespace() {
return ignoreWhitespaceLevel;
}
}

View File

@@ -40,9 +40,16 @@ public class GitDiffResultCommand extends AbstractGitCommand implements DiffResu
super(context);
}
public DiffResult getDiffResult(DiffCommandRequest diffCommandRequest) throws IOException {
public DiffResult getDiffResult(DiffCommandRequest request) throws IOException {
org.eclipse.jgit.lib.Repository repository = open();
return new GitDiffResult(this.repository, repository, Differ.diff(repository, diffCommandRequest), 0, null);
return new GitDiffResult(
this.repository,
repository,
Differ.diff(repository, request),
request.getIgnoreWhitespaceLevel(),
0,
null
);
}
@Override
@@ -50,7 +57,14 @@ public class GitDiffResultCommand extends AbstractGitCommand implements DiffResu
org.eclipse.jgit.lib.Repository repository = open();
int offset = request.getOffset() == null ? 0 : request.getOffset();
try {
return new GitDiffResult(this.repository, repository, Differ.diff(repository, request), offset, request.getLimit());
return new GitDiffResult(
this.repository,
repository,
Differ.diff(repository, request),
request.getIgnoreWhitespaceLevel(),
offset,
request.getLimit()
);
} catch (AmbiguousObjectException ex) {
throw new NotUniqueRevisionException(Repository.class, context.getRepository().getId());
}

View File

@@ -41,6 +41,7 @@ import sonia.scm.repository.Modifications;
import sonia.scm.repository.Modified;
import sonia.scm.repository.Removed;
import sonia.scm.repository.Renamed;
import sonia.scm.repository.api.IgnoreWhitespaceLevel;
import java.io.IOException;
import java.text.MessageFormat;