diff --git a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Commit.java b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Commit.java index b19cf8f075427d3e0bb175a5458e3445bfc8f9e9..d60edd277a89602b7f4fe9e5b014f93aac79deb3 100644 --- a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Commit.java +++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Commit.java @@ -1,23 +1,44 @@ package de.uni_passau.fim.seibt.gitwrapper.repo; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; import java.util.logging.Logger; +import java.util.stream.Collectors; + +import de.uni_passau.fim.seibt.gitwrapper.repo.GitWrapper.ExecRes; public class Commit { private static final Logger LOG = Logger.getLogger(Commit.class.getCanonicalName()); - private Repository repo; private GitWrapper git; + private Repository repo; private String id; - public Commit(Repository repo, String id) { - this.repo = repo; + Commit(Repository repo, String id) { this.git = repo.getGit(); + this.repo = repo; this.id = id; } + public List<Commit> getParents() { + Optional<ExecRes> revList = git.exec(repo.getDir(), "rev-list", "--parents", "-n", "1", id); + Function<ExecRes, List<Commit>> toParentsList = res -> { + String[] ids = res.output.split("\\s+"); + + LOG.fine(() -> String.format("Found %d parents for %s.", ids.length - 1, this)); + + return Arrays.stream(ids).skip(1).map(repo::getCommit).collect(Collectors.toList()); + }; + + return revList.map(toParentsList).orElse(Collections.emptyList()); + } + public String getId() { return id; } diff --git a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java index 158bc436efa36230e51c1489ea9cdd520d59fc2a..c80fe49049f03d8380f6e6ba720131eb104d2fc9 100644 --- a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java +++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java @@ -4,7 +4,9 @@ import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.function.Function; @@ -26,6 +28,8 @@ public class Repository { private String url; private File dir; + private Map<String, Commit> commits; + /** * Constructs a new {@link Repository}. * @@ -46,6 +50,8 @@ public class Repository { LOG.log(Level.WARNING, e, () -> "Exception computing the canonical file for " + dir + ". Using the absolute file instead."); this.dir = dir.getAbsoluteFile(); } + + this.commits = new HashMap<>(); } /** @@ -60,12 +66,23 @@ public class Repository { LOG.fine(() -> String.format("Found %d merge commits in %s.", lines.length, this)); - return Arrays.stream(lines).map(id -> new Commit(this, id)).collect(Collectors.toList()); + return Arrays.stream(lines).map(this::getCommit).collect(Collectors.toList()); }; return revList.map(toCommitList).orElse(Collections.emptyList()); } + /** + * Returns a {@link Commit} for the given id. The <code>id</code> is not checked for validity, this method + * only ensures that only one {@link Commit} object is created for every <code>id</code>. + * + * @param id the ID of the commit + * @return the {@link Commit} + */ + public Commit getCommit(String id) { + return commits.computeIfAbsent(id, theID -> new Commit(this, theID)); + } + public GitWrapper getGit() { return git; }