Switch changelogs to Git

Requires a local repo checkout
diff --git a/pom.xml b/pom.xml
index df8f3ed..1d2c670 100644
--- a/pom.xml
+++ b/pom.xml
@@ -93,11 +93,11 @@
             <version>1.8.2</version>
         </dependency>
 
-        <!-- Retrieve changelog data from SVN -->
+        <!-- Retrieve changelog data from Git -->
         <dependency>
-            <groupId>org.tmatesoft.svnkit</groupId>
-            <artifactId>svnkit</artifactId>
-            <version>1.8.11</version>
+            <groupId>org.eclipse.jgit</groupId>
+            <artifactId>org.eclipse.jgit</artifactId>
+            <version>5.1.2.201810061102-r</version>
         </dependency>
 
         <!-- Parse Jira JSON responses -->
@@ -129,6 +129,17 @@
                             <mainClass>org.apache.sling.tooling.lc.Main</mainClass>
                         </transformer>
                     </transformers>
+                    <!-- Don't propagate signatures from signed jars  -->
+                    <filters>
+                        <filter>
+                            <artifact>org.eclipse.jgit:org.eclipse.jgit</artifact>
+                            <excludes>
+                                <exclude>META-INF/*.SF</exclude>
+                                <exclude>META-INF/*.DSA</exclude>
+                                <exclude>META-INF/*.RSA</exclude>
+                            </excludes>
+                        </filter>
+                    </filters>
                 </configuration>
                 <executions>
                     <execution>
diff --git a/src/main/java/org/apache/sling/tooling/lc/LaunchpadComparer.java b/src/main/java/org/apache/sling/tooling/lc/LaunchpadComparer.java
index c7ab92d..6392e74 100644
--- a/src/main/java/org/apache/sling/tooling/lc/LaunchpadComparer.java
+++ b/src/main/java/org/apache/sling/tooling/lc/LaunchpadComparer.java
@@ -38,9 +38,9 @@
 import org.apache.sling.tooling.lc.aether.ArtifactKey;
 import org.apache.sling.tooling.lc.aether.Artifacts;
 import org.apache.sling.tooling.lc.aether.VersionChange;
+import org.apache.sling.tooling.lc.git.GitChangeLogFinder;
 import org.apache.sling.tooling.lc.jira.IssueFinder;
-import org.apache.sling.tooling.lc.svn.SvnChangeLogFinder;
-import org.tmatesoft.svn.core.SVNException;
+import org.eclipse.jgit.api.errors.GitAPIException;
 
 import com.google.common.collect.Sets;
 
@@ -50,10 +50,12 @@
 
     private final String firstVersion;
     private final String secondVersion;
+    private final String slingRepoCheckout;
 
-    public LaunchpadComparer(String firstVersion, String secondVersion) {
+    public LaunchpadComparer(String firstVersion, String secondVersion, String slingRepoCheckout) {
         this.firstVersion = firstVersion;
         this.secondVersion = secondVersion;
+        this.slingRepoCheckout = slingRepoCheckout;
     }
 
     public void run() throws Exception {
@@ -98,7 +100,7 @@
         System.out.println("Changed");
         changed.entrySet().stream()
             .sorted( (a, b) -> a.getKey().compareTo(b.getKey()) )
-            .forEach(LaunchpadComparer::outputFormatted);        
+            .forEach(this::outputFormatted);        
         
     }
 
@@ -122,7 +124,7 @@
         
     }
 
-    private static void outputFormatted(Map.Entry<ArtifactKey, VersionChange> e) {
+    private void outputFormatted(Map.Entry<ArtifactKey, VersionChange> e) {
         
         ArtifactKey artifact = e.getKey();
         VersionChange versionChange = e.getValue();
@@ -133,12 +135,10 @@
             return;
         }
         
-        SvnChangeLogFinder svn = new SvnChangeLogFinder();
+        GitChangeLogFinder git = new GitChangeLogFinder(slingRepoCheckout);
         
-        String fromTag = artifact.getArtifactId()+"-"+versionChange.getFrom();
-        String toTag = artifact.getArtifactId()+"-"+ versionChange.getTo();
         try {
-            List<String> issues = svn.getChanges(fromTag, toTag)
+            List<String> issues = git.getChanges(artifact.getArtifactId(), versionChange.getFrom(), versionChange.getTo())
                 .stream()
                 .map( m -> m.split(System.lineSeparator())[0])
                 .map(LaunchpadComparer::toJiraKey)
@@ -149,7 +149,7 @@
             issueFinder.findIssues(issues).
                 forEach( i -> System.out.format("        %-10s - %s%n", i.getKey(), i.getSummary()));
             
-        } catch (SVNException | IOException e1) {
+        } catch (GitAPIException | IOException e1) {
             System.err.println("Failed retrieving changes : " + e1.getMessage());
         }
     }
diff --git a/src/main/java/org/apache/sling/tooling/lc/Main.java b/src/main/java/org/apache/sling/tooling/lc/Main.java
index 1ff8632..46e8d63 100644
--- a/src/main/java/org/apache/sling/tooling/lc/Main.java
+++ b/src/main/java/org/apache/sling/tooling/lc/Main.java
@@ -27,6 +27,6 @@
             secondVersion = args[1];
         }
         
-        new LaunchpadComparer(firstVersion, secondVersion).run();
+        new LaunchpadComparer(firstVersion, secondVersion, "..").run();
     }
 }
diff --git a/src/main/java/org/apache/sling/tooling/lc/git/GitChangeLogFinder.java b/src/main/java/org/apache/sling/tooling/lc/git/GitChangeLogFinder.java
new file mode 100644
index 0000000..ad598d6
--- /dev/null
+++ b/src/main/java/org/apache/sling/tooling/lc/git/GitChangeLogFinder.java
@@ -0,0 +1,69 @@
+package org.apache.sling.tooling.lc.git;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+
+public class GitChangeLogFinder {
+    
+    public static void main(String[] args) throws IOException, GitAPIException  {
+        new GitChangeLogFinder("..").getChanges("org.apache.sling.adapter", "2.1.2", "2.1.6")
+            .stream().forEach(System.out::println);
+    }
+    
+    private final String slingRepoCheckoutDir;
+    
+    /**
+     * @param slingRepoCheckoutDir the <tt>repo</tt> root for Apache Sling
+     */
+    public GitChangeLogFinder(String slingRepoCheckoutDir) {
+        this.slingRepoCheckoutDir = slingRepoCheckoutDir;
+    }
+
+    public List<String> getChanges(String artifactId, String from, String to) throws IOException, GitAPIException {
+        
+        Path repoPath = Paths.get(slingRepoCheckoutDir, artifactId.replace('.', '-'), ".git");
+        
+        FileRepositoryBuilder repositoryBuilder = new FileRepositoryBuilder();
+        
+        Repository repository = repositoryBuilder.setGitDir(repoPath.toFile())
+                .readEnvironment() // scan environment GIT_* variables
+                .findGitDir() // scan up the file system tree
+                .setMustExist(true)
+                .build();
+
+        Ref fromTag = getTagChecked(repository, artifactId, from);
+        Ref toTag = getTagChecked(repository, artifactId, to);
+        
+        Git git = Git.wrap(repository);
+        
+        fromTag = repository.getRefDatabase().peel(fromTag);
+        toTag = repository.getRefDatabase().peel(toTag);
+        
+        List<String> commits = new ArrayList<>();
+        git.log()
+            .addRange(fromTag.getPeeledObjectId(), toTag.getPeeledObjectId())
+            .call()
+            .forEach( c -> commits.add(c.getShortMessage()));
+        
+        return commits;
+    }
+
+    private Ref getTagChecked(Repository repository, String artifactId, String version) throws IOException {
+        
+        final String tagName = artifactId + "-" + version;
+        final Ref ref = repository.getRefDatabase().getRef(Constants.R_TAGS + tagName);
+        if ( ref == null )
+            throw new RuntimeException("No tag " + tagName + " found in git repo at " + repository.getDirectory());
+        return ref;
+    }
+}
diff --git a/src/main/java/org/apache/sling/tooling/lc/svn/SvnChangeLogFinder.java b/src/main/java/org/apache/sling/tooling/lc/svn/SvnChangeLogFinder.java
deleted file mode 100644
index 44dc663..0000000
--- a/src/main/java/org/apache/sling/tooling/lc/svn/SvnChangeLogFinder.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.sling.tooling.lc.svn;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.tmatesoft.svn.core.SVNDirEntry;
-import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNURL;
-import org.tmatesoft.svn.core.io.SVNRepository;
-import org.tmatesoft.svn.core.wc.SVNClientManager;
-import org.tmatesoft.svn.core.wc.SVNRevision;
-
-public class SvnChangeLogFinder {
-    
-    private static final String SLING_SVN_REPO_BASE = "https://svn.apache.org/repos/asf/sling";
-    
-    public static void main(String[] args) throws SVNException {
-        
-        new SvnChangeLogFinder().getChanges("org.apache.sling.adapter-2.1.2", "org.apache.sling.adapter-2.1.6")
-            .stream().forEach(System.out::println);
-    }
-    
-    public List<String> getChanges(String first, String second) throws SVNException {
-        
-        SVNURL svnUrl = SVNURL.parseURIEncoded(SLING_SVN_REPO_BASE);
-        
-        List<String> changes = new ArrayList<>();
-        
-        SVNClientManager manager  = SVNClientManager.newInstance();
-        
-        SVNRepository repo = manager.getRepositoryPool().createRepository(svnUrl, true);
-        
-        final long fromRev = getRevision(first, repo);
-        final long toRev = getRevision(second, repo);
-        
-        if ( fromRev == -1 || toRev == -1 ) {
-            System.err.println("Failed retrieving changes from SVN; revisions were " + fromRev + " and " + toRev);
-            return Collections.emptyList();
-        }
-        
-        SVNRevision from = SVNRevision.create(fromRev);
-        SVNRevision to = SVNRevision.create(toRev);
-        
-        repo.log(new String[] { "tags/" + second } ,from.getNumber(), to.getNumber(), false, false, (e) -> changes.add(e.getMessage()));
-        
-        return changes;
-    }
-
-
-    private long getRevision(String tagName, SVNRepository repo) throws SVNException {
-        
-        SVNDirEntry info = repo.info("tags/" + tagName, -1);
-        if ( info == null ) 
-            return -1;
-        
-        return info.getRevision();
-    }
-
-}