From 7249c3758eddd0dc21d741f937fa72a9b5ce6eff Mon Sep 17 00:00:00 2001
From: Georg Seibt <seibt@fim.uni-passau.de>
Date: Tue, 12 Apr 2016 15:32:23 +0200
Subject: [PATCH] get merge commits

---
 .../fim/seibt/gitwrapper/repo/Commit.java     | 48 +++++++++++
 .../fim/seibt/gitwrapper/repo/GitWrapper.java |  9 ++-
 .../fim/seibt/gitwrapper/repo/Repository.java | 79 +++++++++++++++++--
 3 files changed, 128 insertions(+), 8 deletions(-)
 create mode 100644 src/de/uni_passau/fim/seibt/gitwrapper/repo/Commit.java

diff --git a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Commit.java b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Commit.java
new file mode 100644
index 0000000..b19cf8f
--- /dev/null
+++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Commit.java
@@ -0,0 +1,48 @@
+package de.uni_passau.fim.seibt.gitwrapper.repo;
+
+import java.util.Objects;
+import java.util.logging.Logger;
+
+public class Commit {
+
+    private static final Logger LOG = Logger.getLogger(Commit.class.getCanonicalName());
+
+    private Repository repo;
+    private GitWrapper git;
+
+    private String id;
+
+    public Commit(Repository repo, String id) {
+        this.repo = repo;
+        this.git = repo.getGit();
+        this.id = id;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        Commit commit = (Commit) o;
+        return Objects.equals(repo, commit.repo) && Objects.equals(id, commit.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(repo, id);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("Commit{id='%s'}", id);
+    }
+}
diff --git a/src/de/uni_passau/fim/seibt/gitwrapper/repo/GitWrapper.java b/src/de/uni_passau/fim/seibt/gitwrapper/repo/GitWrapper.java
index 08ae56e..bacee2a 100644
--- a/src/de/uni_passau/fim/seibt/gitwrapper/repo/GitWrapper.java
+++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/GitWrapper.java
@@ -25,9 +25,12 @@ public class GitWrapper {
     private static final Pattern CLONING_INTO = Pattern.compile("Cloning into '(.*)'\\.\\.\\.");
     private static final Pattern ALREADY_EXISTS = Pattern.compile("fatal: destination path '(.*)' already exists and is not an empty directory\\.");
 
-    private class ExecRes {
-        private int code;
-        private String output;
+    /**
+     * The result of a command line execution.
+     */
+    static class ExecRes {
+        int code;
+        String output;
     }
 
     private String git;
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 705a02a..158bc43 100644
--- a/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java
+++ b/src/de/uni_passau/fim/seibt/gitwrapper/repo/Repository.java
@@ -1,13 +1,27 @@
 package de.uni_passau.fim.seibt.gitwrapper.repo;
 
 import java.io.File;
+import java.io.IOException;
+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.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import de.uni_passau.fim.seibt.gitwrapper.repo.GitWrapper.ExecRes;
 
 /**
  * A git {@link Repository}.
  */
 public class Repository {
 
-    private GitWrapper gitWrapper;
+    private static final Logger LOG = Logger.getLogger(Repository.class.getCanonicalName());
+
+    private GitWrapper git;
 
     private String url;
     private File dir;
@@ -15,17 +29,72 @@ public class Repository {
     /**
      * Constructs a new {@link Repository}.
      *
-     * @param gitWrapper
+     * @param git
      *         the {@link GitWrapper} to use
      * @param url
      *         the url the {@link Repository} was cloned from
      * @param dir
      *         the directory containing the {@link Repository}
      */
-    Repository(GitWrapper gitWrapper, String url, File dir) {
-        this.gitWrapper = gitWrapper;
+    Repository(GitWrapper git, String url, File dir) {
+        this.git = git;
         this.url = url;
-        this.dir = dir;
+
+        try {
+            this.dir = dir.getCanonicalFile();
+        } catch (IOException e) {
+            LOG.log(Level.WARNING, e, () -> "Exception computing the canonical file for " + dir + ". Using the absolute file instead.");
+            this.dir = dir.getAbsoluteFile();
+        }
+    }
+
+    /**
+     * Returns the merge commits in this repository.
+     *
+     * @return the merge commits
+     */
+    public List<Commit> getMergeCommits() {
+        Optional<ExecRes> revList = git.exec(dir, "rev-list", "--all", "--merges");
+        Function<ExecRes, List<Commit>> toCommitList = res -> {
+            String[] lines = res.output.split("[\\r?\\n]+");
+
+            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 revList.map(toCommitList).orElse(Collections.emptyList());
+    }
+
+    public GitWrapper getGit() {
+        return git;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public File getDir() {
+        return dir;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        Repository that = (Repository) o;
+        return Objects.equals(url, that.url) && Objects.equals(dir, that.dir);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(url, dir);
     }
 
     @Override
-- 
GitLab