This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit f183adf3be7874ee4b124aaa6f13470e0b13f669
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Thu Oct 24 09:00:34 2024 -0400

    Git Improvements
---
 .../apache/camel/karavan/service/GitService.java   | 88 +++++++++++++++++++++-
 1 file changed, 87 insertions(+), 1 deletion(-)

diff --git 
a/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java 
b/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java
index d1e81300..83660f3b 100644
--- a/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java
+++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java
@@ -29,23 +29,31 @@ import org.eclipse.jgit.api.errors.InvalidRemoteException;
 import org.eclipse.jgit.api.errors.RefNotFoundException;
 import org.eclipse.jgit.api.errors.TransportException;
 import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffFormatter;
 import org.eclipse.jgit.lib.*;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevTree;
+import org.eclipse.jgit.revwalk.RevWalk;
 import org.eclipse.jgit.transport.*;
 import org.eclipse.jgit.transport.ssh.jsch.JschConfigSessionFactory;
+import org.eclipse.jgit.treewalk.AbstractTreeIterator;
+import org.eclipse.jgit.treewalk.CanonicalTreeParser;
 import org.eclipse.jgit.treewalk.TreeWalk;
 import org.eclipse.jgit.treewalk.filter.TreeFilter;
 import org.eclipse.microprofile.config.inject.ConfigProperty;
 import org.jboss.logging.Logger;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.*;
 import java.util.regex.Pattern;
+import java.util.stream.StreamSupport;
 
 @ApplicationScoped
 public class GitService {
@@ -179,7 +187,7 @@ public class GitService {
         LOGGER.info("Temp folder created " + folder);
         Git git = null;
         if (ephemeral) {
-            LOGGER.error("New ephemeral repository");
+            LOGGER.warn("New ephemeral repository");
             git = init(folder, gitConfig.getUri(), gitConfig.getBranch());
         } else {
             try {
@@ -462,4 +470,82 @@ public class GitService {
         }
         return sshSessionFactory;
     }
+
+    public List<ProjectCommit> getProjectCommits(String projectId) {
+        List<ProjectCommit> result = new ArrayList<>();
+        try {
+            Git pollGit = getGit(true, 
vertx.fileSystem().createTempDirectoryBlocking("commits"));
+            if (pollGit != null) {
+                
StreamSupport.stream(pollGit.log().all().addPath(projectId).call().spliterator(),
 false)
+                        
.sorted(Comparator.comparingInt(RevCommit::getCommitTime))
+                        .forEach(commit -> {
+                            var diffs = getProjectFileCommitDiffs(pollGit, 
commit);
+                            var projectCommit = new 
ProjectCommit(commit.getId().getName(), projectId,
+                                    commit.getAuthorIdent().getName(), 
commit.getAuthorIdent().getEmailAddress(),
+                                    commit.getShortMessage(), diffs);
+                            result.add(projectCommit);
+                        });
+            }
+        } catch (Exception e) {
+            LOGGER.error("Error", e);
+        }
+        return result;
+    }
+
+    private List<ProjectFileCommitDiff> getProjectFileCommitDiffs(Git git, 
RevCommit commit) {
+        List<ProjectFileCommitDiff> result = new ArrayList<>();
+        var repository = git.getRepository();
+        try {
+            try (RevWalk revWalk = new RevWalk(repository)) {
+                if (commit.getParentCount() > 0) {
+                    RevCommit parentCommit = commit.getParent(0);
+                    revWalk.parseCommit(parentCommit);
+
+                    AbstractTreeIterator oldTreeIter = 
prepareTreeParser(repository, parentCommit);
+                    AbstractTreeIterator newTreeIter = 
prepareTreeParser(repository, commit);
+
+                    try (ByteArrayOutputStream baos = new 
ByteArrayOutputStream();
+                         DiffFormatter diffFormatter = new 
DiffFormatter(baos)) {
+                        diffFormatter.setRepository(repository);
+                        List<DiffEntry> diffs = 
diffFormatter.scan(oldTreeIter, newTreeIter);
+
+                        for (DiffEntry diff : diffs) {
+                            diffFormatter.format(diff);
+                            var fileDiff = new 
ProjectFileCommitDiff(diff.getChangeType().name(), diff.getNewPath(), 
diff.getOldPath(), baos.toString(StandardCharsets.UTF_8));
+                            result.add(fileDiff);
+                            baos.reset();  // Clear the output stream for the 
next diff
+                        }
+                    }
+                } else {
+                    try (TreeWalk treeWalk = new TreeWalk(repository)) {
+                        treeWalk.addTree(commit.getTree());
+                        treeWalk.setRecursive(true);
+                        while (treeWalk.next()) {
+                            // Get the object ID for the file (blob)
+                            ObjectId objectId = treeWalk.getObjectId(0);
+                            // Load the file content
+                            ObjectLoader loader = repository.open(objectId);
+                            byte[] content = loader.getBytes();
+                            var fileDiff = new 
ProjectFileCommitDiff(DiffEntry.ChangeType.ADD.name(), 
treeWalk.getPathString(), DiffEntry.DEV_NULL, new String(content, 
StandardCharsets.UTF_8));
+                            result.add(fileDiff);
+                        }
+                    }
+                }
+            }
+        } catch (IOException e) {
+           LOGGER.error("Error", e);
+        }
+        return result;
+    }
+
+    private static AbstractTreeIterator prepareTreeParser(Repository 
repository, RevCommit commit) throws IOException {
+        try (RevWalk walk = new RevWalk(repository)) {
+            RevTree tree = walk.parseTree(commit.getTree().getId());
+            CanonicalTreeParser treeParser = new CanonicalTreeParser();
+            try (ObjectReader reader = repository.newObjectReader()) {
+                treeParser.reset(reader, tree.getId());
+            }
+            return treeParser;
+        }
+    }
 }

Reply via email to