All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.bjurr.violations.git.ViolationsGitRepo Maven / Gradle / Ivy

The newest version!
package se.bjurr.violations.git;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
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.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import se.bjurr.violations.git.data.DiffsPerFile;

public final class ViolationsGitRepo {

  private ViolationsGitRepo() {}

  public static DiffsPerFile diff(final File repo, final String from, final String to)
      throws Exception {
    final Map patchPerFile = new TreeMap<>();
    Git git = null;
    Repository repository = null;
    try {
      repository = getGitRepo(repo);
      final ObjectId fromObjectId = getObjectId(repository, from);
      final ObjectId toObjectId = getObjectId(repository, to);

      git = new Git(repository);
      final AbstractTreeIterator oldTree = getTree(repository, fromObjectId);
      final AbstractTreeIterator newTree = getTree(repository, toObjectId);
      final List diffs = git.diff().setOldTree(oldTree).setNewTree(newTree).call();

      for (final DiffEntry diff : diffs) {
        final String patchString = toPatchString(repository, diff);
        final String path = diff.getNewPath();
        patchPerFile.put(path, patchString);
      }
    } catch (final IOException e) {
      throw new RuntimeException("Could not use GIT repo in " + repo.getAbsolutePath(), e);
    } finally {
      if (repository != null) {
        repository.close();
      }
      if (git != null) {
        git.close();
      }
    }
    return new DiffsPerFile(patchPerFile);
  }

  private static String toPatchString(final Repository repository, final DiffEntry diff)
      throws IOException, UnsupportedEncodingException {
    final ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (final DiffFormatter df = new DiffFormatter(out)) {
      df.setRepository(repository);
      df.setContext(0);
      df.format(diff);
      final RawText r = new RawText(out.toByteArray());
      r.getLineDelimiter();
    }
    final String patchString = out.toString("UTF-8");
    out.reset();
    return patchString;
  }

  private static AbstractTreeIterator getTree(final Repository repository, final ObjectId objectId)
      throws Exception {
    try (RevWalk walk = new RevWalk(repository)) {
      final RevCommit commit = walk.parseCommit(objectId);
      final RevTree tree = walk.parseTree(commit.getTree().getId());

      final CanonicalTreeParser treeParser = new CanonicalTreeParser();
      try (ObjectReader reader = repository.newObjectReader()) {
        treeParser.reset(reader, tree.getId());
      }

      return treeParser;
    }
  }

  private static ObjectId getObjectId(final Repository repository, final String revstr)
      throws Exception {
    final ObjectId resolved = repository.resolve(revstr);
    if (resolved == null) {
      throw new RuntimeException("Could not resolve \"" + revstr + "\"");
    }
    return resolved;
  }

  private static Repository getGitRepo(final File repo) throws IOException {
    File repoFile = new File(repo.getAbsolutePath());
    final File gitRepoFile = new File(repo.getAbsolutePath() + "/.git");
    if (gitRepoFile.exists()) {
      repoFile = gitRepoFile;
    }
    final FileRepositoryBuilder builder =
        new FileRepositoryBuilder() //
            .findGitDir(repoFile) //
            .readEnvironment();
    if (builder.getGitDir() == null) {
      throw new RuntimeException("Did not find a GIT repo in " + repo.getAbsolutePath());
    }
    return builder.build();
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy