mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 15:35:49 +01:00
implement first diff details
This commit is contained in:
@@ -6,7 +6,7 @@ public interface DiffFile extends Iterable<Hunk> {
|
|||||||
|
|
||||||
String getNewRevision();
|
String getNewRevision();
|
||||||
|
|
||||||
String getOldName();
|
String getOldPath();
|
||||||
|
|
||||||
String getNewName();
|
String getNewPath();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package sonia.scm.repository.spi;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import org.eclipse.jgit.diff.DiffEntry;
|
||||||
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
|
import org.eclipse.jgit.revwalk.RevTree;
|
||||||
|
import org.eclipse.jgit.revwalk.RevWalk;
|
||||||
|
import org.eclipse.jgit.treewalk.EmptyTreeIterator;
|
||||||
|
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||||
|
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||||
|
import sonia.scm.repository.GitUtil;
|
||||||
|
import sonia.scm.util.Util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
final class Differ implements AutoCloseable {
|
||||||
|
|
||||||
|
private final RevWalk walk;
|
||||||
|
private final TreeWalk treeWalk;
|
||||||
|
private final RevCommit commit;
|
||||||
|
|
||||||
|
private Differ(RevCommit commit, RevWalk walk, TreeWalk treeWalk) {
|
||||||
|
this.commit = commit;
|
||||||
|
this.walk = walk;
|
||||||
|
this.treeWalk = treeWalk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Differ create(Repository repository, DiffCommandRequest request) throws IOException {
|
||||||
|
RevWalk walk = new RevWalk(repository);
|
||||||
|
|
||||||
|
ObjectId revision = repository.resolve(request.getRevision());
|
||||||
|
RevCommit commit = walk.parseCommit(revision);
|
||||||
|
|
||||||
|
walk.markStart(commit);
|
||||||
|
commit = walk.next();
|
||||||
|
TreeWalk treeWalk = new TreeWalk(repository);
|
||||||
|
treeWalk.reset();
|
||||||
|
treeWalk.setRecursive(true);
|
||||||
|
|
||||||
|
if (Util.isNotEmpty(request.getPath()))
|
||||||
|
{
|
||||||
|
treeWalk.setFilter(PathFilter.create(request.getPath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!Strings.isNullOrEmpty(request.getAncestorChangeset()))
|
||||||
|
{
|
||||||
|
ObjectId otherRevision = repository.resolve(request.getAncestorChangeset());
|
||||||
|
ObjectId ancestorId = computeCommonAncestor(repository, revision, otherRevision);
|
||||||
|
RevTree tree = walk.parseCommit(ancestorId).getTree();
|
||||||
|
treeWalk.addTree(tree);
|
||||||
|
}
|
||||||
|
else if (commit.getParentCount() > 0)
|
||||||
|
{
|
||||||
|
RevTree tree = commit.getParent(0).getTree();
|
||||||
|
|
||||||
|
if (tree != null)
|
||||||
|
{
|
||||||
|
treeWalk.addTree(tree);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
treeWalk.addTree(new EmptyTreeIterator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
treeWalk.addTree(new EmptyTreeIterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
treeWalk.addTree(commit.getTree());
|
||||||
|
|
||||||
|
return new Differ(commit, walk, treeWalk);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ObjectId computeCommonAncestor(org.eclipse.jgit.lib.Repository repository, ObjectId revision1, ObjectId revision2) throws IOException {
|
||||||
|
return GitUtil.computeCommonAncestor(repository, revision1, revision2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void process(Consumer<Diff> diffConsumer) throws IOException {
|
||||||
|
List<DiffEntry> entries = DiffEntry.scan(treeWalk);
|
||||||
|
diffConsumer.accept(new Diff(commit, entries));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
GitUtil.release(walk);
|
||||||
|
GitUtil.release(treeWalk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Diff {
|
||||||
|
|
||||||
|
private final RevCommit commit;
|
||||||
|
private final List<DiffEntry> entries;
|
||||||
|
|
||||||
|
private Diff(RevCommit commit, List<DiffEntry> entries) {
|
||||||
|
this.commit = commit;
|
||||||
|
this.entries = entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RevCommit getCommit() {
|
||||||
|
return commit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DiffEntry> getEntries() {
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package sonia.scm.repository.spi;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.diff.DiffEntry;
|
||||||
|
import sonia.scm.repository.GitUtil;
|
||||||
|
import sonia.scm.repository.Repository;
|
||||||
|
import sonia.scm.repository.api.DiffFile;
|
||||||
|
import sonia.scm.repository.api.DiffResult;
|
||||||
|
import sonia.scm.repository.api.Hunk;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class GitDiffResultCommand extends AbstractGitCommand implements DiffResultCommand {
|
||||||
|
|
||||||
|
GitDiffResultCommand(GitContext context, Repository repository) {
|
||||||
|
super(context, repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiffResult getDiffResult(DiffCommandRequest diffCommandRequest) throws IOException {
|
||||||
|
try (Differ differ = Differ.create(open(), diffCommandRequest)) {
|
||||||
|
GitDiffResult result = new GitDiffResult();
|
||||||
|
differ.process(result::process);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class GitDiffResult implements DiffResult {
|
||||||
|
|
||||||
|
private Differ.Diff diff;
|
||||||
|
|
||||||
|
void process(Differ.Diff diff) {
|
||||||
|
this.diff = diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOldRevision() {
|
||||||
|
return GitUtil.getId(diff.getCommit().getParent(0).getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNewRevision() {
|
||||||
|
return GitUtil.getId(diff.getCommit().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<DiffFile> iterator() {
|
||||||
|
return diff.getEntries().stream().map(GitDiffFile::new).collect(Collectors.<DiffFile>toList()).iterator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GitDiffFile implements DiffFile {
|
||||||
|
|
||||||
|
private final DiffEntry diffEntry;
|
||||||
|
|
||||||
|
private GitDiffFile(DiffEntry diffEntry) {
|
||||||
|
this.diffEntry = diffEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOldRevision() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNewRevision() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOldPath() {
|
||||||
|
return diffEntry.getOldPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNewPath() {
|
||||||
|
return diffEntry.getNewPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Hunk> iterator() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package sonia.scm.repository.spi;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import sonia.scm.repository.api.DiffFile;
|
||||||
|
import sonia.scm.repository.api.DiffResult;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class GitDiffResultCommandTest extends AbstractGitCommandTestBase {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnOldAndNewRevision() throws IOException {
|
||||||
|
GitDiffResultCommand gitDiffResultCommand = new GitDiffResultCommand(createContext(), repository);
|
||||||
|
DiffCommandRequest diffCommandRequest = new DiffCommandRequest();
|
||||||
|
diffCommandRequest.setRevision("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4");
|
||||||
|
|
||||||
|
DiffResult diffResult = gitDiffResultCommand.getDiffResult(diffCommandRequest);
|
||||||
|
|
||||||
|
assertThat(diffResult.getNewRevision()).isEqualTo("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4");
|
||||||
|
assertThat(diffResult.getOldRevision()).isEqualTo("592d797cd36432e591416e8b2b98154f4f163411");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnFilePaths() throws IOException {
|
||||||
|
GitDiffResultCommand gitDiffResultCommand = new GitDiffResultCommand(createContext(), repository);
|
||||||
|
DiffCommandRequest diffCommandRequest = new DiffCommandRequest();
|
||||||
|
diffCommandRequest.setRevision("3f76a12f08a6ba0dc988c68b7f0b2cd190efc3c4");
|
||||||
|
|
||||||
|
DiffResult diffResult = gitDiffResultCommand.getDiffResult(diffCommandRequest);
|
||||||
|
Iterator<DiffFile> iterator = diffResult.iterator();
|
||||||
|
DiffFile a = iterator.next();
|
||||||
|
assertThat(a.getNewPath()).isEqualTo("a.txt");
|
||||||
|
assertThat(a.getOldPath()).isEqualTo("a.txt");
|
||||||
|
|
||||||
|
DiffFile b = iterator.next();
|
||||||
|
assertThat(b.getOldPath()).isEqualTo("b.txt");
|
||||||
|
assertThat(b.getNewPath()).isEqualTo("/dev/null");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user