Use jgit client library for diff with conflict

This commit is contained in:
Rene Pfeuffer
2019-11-07 16:26:30 +01:00
parent df144e298c
commit 758e4ab750
3 changed files with 46 additions and 13 deletions

View File

@@ -115,7 +115,7 @@ public final class DiffCommandRequest extends FileBaseCommandRequest
this.ancestorChangeset = ancestorChangeset; this.ancestorChangeset = ancestorChangeset;
} }
public void setMergeChangeset(String mergeChangeset) { public void setConflictBranch(String mergeChangeset) {
this.mergeChangeset = mergeChangeset; this.mergeChangeset = mergeChangeset;
} }

View File

@@ -37,12 +37,15 @@ import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter; import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import sonia.scm.repository.GitWorkdirFactory; import sonia.scm.repository.GitWorkdirFactory;
import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.Repository; import sonia.scm.repository.Repository;
import sonia.scm.repository.api.DiffCommandBuilder; import sonia.scm.repository.api.DiffCommandBuilder;
import java.io.IOException; import java.io.IOException;
import java.util.List;
/** /**
* *
@@ -61,7 +64,9 @@ public class GitDiffCommand extends AbstractGitCommand implements DiffCommand {
public DiffCommandBuilder.OutputStreamConsumer getDiffResult(DiffCommandRequest request) throws IOException { public DiffCommandBuilder.OutputStreamConsumer getDiffResult(DiffCommandRequest request) throws IOException {
WorkingCopyCloser closer = new WorkingCopyCloser(); WorkingCopyCloser closer = new WorkingCopyCloser();
if (Strings.isNullOrEmpty(request.getMergeChangeset())) { if (Strings.isNullOrEmpty(request.getMergeChangeset())) {
return computeDiff(request, open(), closer); Differ.Diff diff = Differ.diff(open(), request);
List<DiffEntry> entries = diff.getEntries();
return computeDiff(entries, open(), closer);
} else { } else {
return inCloneWithPostponedClose(git -> new GitCloneWorker<DiffCommandBuilder.OutputStreamConsumer>(git) { return inCloneWithPostponedClose(git -> new GitCloneWorker<DiffCommandBuilder.OutputStreamConsumer>(git) {
@Override @Override
@@ -77,22 +82,34 @@ public class GitDiffCommand extends AbstractGitCommand implements DiffCommand {
throw new InternalRepositoryException(context.getRepository(), "could not merge branch " + request.getRevision() + " into " + request.getMergeChangeset(), e); throw new InternalRepositoryException(context.getRepository(), "could not merge branch " + request.getRevision() + " into " + request.getMergeChangeset(), e);
} }
CanonicalTreeParser treeParser = new CanonicalTreeParser();
ObjectId treeId = git.getRepository().resolve(request.getMergeChangeset() + "^{tree}");
return outputStream -> {
try (ObjectReader reader = git.getRepository().newObjectReader()) {
treeParser.reset(reader, treeId);
git
.diff()
.setOldTree(treeParser)
.setOutputStream(outputStream)
.call();
DiffCommandRequest clone = request.clone(); DiffCommandRequest clone = request.clone();
clone.setRevision(sourceRevision.name()); clone.setRevision(sourceRevision.name());
return computeDiff(request, getClone().getRepository(), closer); } catch (GitAPIException e) {
throw new InternalRepositoryException(repository, "could not calculate diff", e);
}
};
} }
}, workdirFactory, request.getMergeChangeset(), closer); }, workdirFactory, request.getMergeChangeset(), closer);
} }
} }
private DiffCommandBuilder.OutputStreamConsumer computeDiff(DiffCommandRequest request, org.eclipse.jgit.lib.Repository repository, WorkingCopyCloser closer) throws IOException { private DiffCommandBuilder.OutputStreamConsumer computeDiff(List<DiffEntry> entries, org.eclipse.jgit.lib.Repository repository, WorkingCopyCloser closer) throws IOException {
Differ.Diff diff = Differ.diff(repository, request);
return output -> { return output -> {
try (DiffFormatter formatter = new DiffFormatter(output)) { try (DiffFormatter formatter = new DiffFormatter(output)) {
formatter.setRepository(repository); formatter.setRepository(repository);
for (DiffEntry e : diff.getEntries()) { for (DiffEntry e : entries) {
if (!e.getOldId().equals(e.getNewId())) { if (!e.getOldId().equals(e.getNewId())) {
formatter.format(e); formatter.format(e);
} }

View File

@@ -12,7 +12,7 @@ import static org.assertj.core.api.Assertions.assertThat;
public class GitDiffCommand_Merge_Test extends AbstractGitCommandTestBase { public class GitDiffCommand_Merge_Test extends AbstractGitCommandTestBase {
static final String DIFF_HEADER = "diff --git a/Main.java b/Main.java"; static final String DIFF_HEADER = "diff --git a/Main.java b/Main.java";
static final String DIFF_FILE_A_MULTIPLE_REVISIONS = "--- a/Main.java\n" + static final String DIFF_FILE_NO_CONFLICT = "--- a/Main.java\n" +
"+++ b/Main.java\n" + "+++ b/Main.java\n" +
"@@ -1,5 +1,5 @@\n" + "@@ -1,5 +1,5 @@\n" +
" class Main {\n" + " class Main {\n" +
@@ -21,6 +21,22 @@ public class GitDiffCommand_Merge_Test extends AbstractGitCommandTestBase {
" System.out.println(\"Expect nothing more to happen.\");\n" + " System.out.println(\"Expect nothing more to happen.\");\n" +
" System.out.println(\"This is for demonstration, only.\");\n" + " System.out.println(\"This is for demonstration, only.\");\n" +
" }\n"; " }\n";
static final String DIFF_FILE_CONFLICT = "--- a/Main.java\n" +
"+++ b/Main.java\n" +
"@@ -1,6 +1,13 @@\n" +
"+import java.util.Arrays;\n" +
"+\n" +
" class Main {\n" +
" public static void main(String[] args) {\n" +
" System.out.println(\"Expect nothing more to happen.\");\n" +
"+<<<<<<< HEAD\n" +
" System.out.println(\"This is for demonstration, only.\");\n" +
"+=======\n" +
"+ System.out.println(\"Parameters:\");\n" +
"+ Arrays.stream(args).map(arg -> \"- \" + arg).forEach(System.out::println);\n" +
"+>>>>>>> feature/print_args\n" +
" }\n" +
" }\n";
@Rule @Rule
public BindTransportProtocolRule transportProtocolRule = new BindTransportProtocolRule(); public BindTransportProtocolRule transportProtocolRule = new BindTransportProtocolRule();
@@ -30,12 +46,12 @@ public class GitDiffCommand_Merge_Test extends AbstractGitCommandTestBase {
GitDiffCommand gitDiffCommand = new GitDiffCommand(createContext(), repository, new SimpleGitWorkdirFactory(new WorkdirProvider())); GitDiffCommand gitDiffCommand = new GitDiffCommand(createContext(), repository, new SimpleGitWorkdirFactory(new WorkdirProvider()));
DiffCommandRequest diffCommandRequest = new DiffCommandRequest(); DiffCommandRequest diffCommandRequest = new DiffCommandRequest();
diffCommandRequest.setRevision("feature/rename_variable"); diffCommandRequest.setRevision("feature/rename_variable");
diffCommandRequest.setMergeChangeset("integration"); diffCommandRequest.setConflictBranch("integration");
ByteArrayOutputStream output = new ByteArrayOutputStream(); ByteArrayOutputStream output = new ByteArrayOutputStream();
gitDiffCommand.getDiffResult(diffCommandRequest).accept(output); gitDiffCommand.getDiffResult(diffCommandRequest).accept(output);
assertThat(output.toString()) assertThat(output.toString())
.contains(DIFF_HEADER) .contains(DIFF_HEADER)
.contains(DIFF_FILE_A_MULTIPLE_REVISIONS); .contains(DIFF_FILE_NO_CONFLICT);
} }
@Test @Test
@@ -43,12 +59,12 @@ public class GitDiffCommand_Merge_Test extends AbstractGitCommandTestBase {
GitDiffCommand gitDiffCommand = new GitDiffCommand(createContext(), repository, new SimpleGitWorkdirFactory(new WorkdirProvider())); GitDiffCommand gitDiffCommand = new GitDiffCommand(createContext(), repository, new SimpleGitWorkdirFactory(new WorkdirProvider()));
DiffCommandRequest diffCommandRequest = new DiffCommandRequest(); DiffCommandRequest diffCommandRequest = new DiffCommandRequest();
diffCommandRequest.setRevision("feature/print_args"); diffCommandRequest.setRevision("feature/print_args");
diffCommandRequest.setMergeChangeset("integration"); diffCommandRequest.setConflictBranch("integration");
ByteArrayOutputStream output = new ByteArrayOutputStream(); ByteArrayOutputStream output = new ByteArrayOutputStream();
gitDiffCommand.getDiffResult(diffCommandRequest).accept(output); gitDiffCommand.getDiffResult(diffCommandRequest).accept(output);
assertThat(output.toString()) assertThat(output.toString())
.contains(DIFF_HEADER) .contains(DIFF_HEADER)
.contains(DIFF_FILE_A_MULTIPLE_REVISIONS); .contains(DIFF_FILE_CONFLICT);
} }
@Override @Override