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

org.openlca.git.repo.Commits Maven / Gradle / Ivy

The newest version!
package org.openlca.git.repo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.openlca.core.model.ModelType;
import org.openlca.git.model.Commit;
import org.openlca.git.util.Constants;
import org.openlca.git.util.GitUtil;
import org.openlca.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Commits {

	private static final Logger log = LoggerFactory.getLogger(Commits.class);
	private final OlcaRepository repo;

	static Commits of(OlcaRepository repo) {
		return new Commits(repo);
	}

	private Commits(OlcaRepository repo) {
		this.repo = repo;
	}

	public Commit get(String id) {
		try {
			var rev = getRev(id);
			if (rev == null)
				return null;
			return new Commit(rev);
		} catch (IOException e) {
			log.error("Error accessing history", e);
			return null;
		}
	}

	public String resolve(String rev) {
		try {
			var id = repo.resolve(rev);
			if (id == null)
				return null;
			return id.getName();
		} catch (IOException e) {
			log.error("Error accessing history", e);
			return null;
		}
	}

	public Commit head() {
		var commit = repo.getHeadCommit();
		if (commit == null)
			return null;
		return new Commit(commit);
	}

	public Commit stash() throws GitAPIException {
		var commits = Git.wrap(repo).stashList().call();
		if (commits == null || commits.isEmpty())
			return null;
		return new Commit(commits.iterator().next());
	}

	RevCommit getRev(String commitId) throws IOException {
		if (commitId != null)
			return repo.parseCommit(ObjectId.fromString(commitId));
		return repo.getHeadCommit();
	}

	public Find find() {
		return new Find();
	}

	public class Find {

		private String start;
		private boolean includeStart;
		private String end;
		private boolean includeEnd;
		private ModelType type;
		private String refId;
		private String path;
		private List branches = List.of(Constants.LOCAL_BRANCH, Constants.LOCAL_REF);

		public Find from(String from) {
			this.includeStart = true;
			this.start = from;
			return this;
		}

		public Find after(String after) {
			this.includeStart = false;
			this.start = after;
			return this;
		}

		public Find until(String until) {
			this.includeEnd = true;
			this.end = until;
			return this;
		}

		public Find before(String before) {
			this.includeEnd = false;
			this.end = before;
			return this;
		}

		public Find path(String path) {
			this.path = path;
			return this;
		}

		public Find type(ModelType type) {
			this.path = type != null ? type.name() : null;
			return this;
		}

		public Find model(ModelType type, String refId) {
			this.type = type;
			this.refId = refId;
			return this;
		}

		public Find refs(String... branches) {
			this.branches = Arrays.asList(branches);
			return this;
		}

		public String latestId() {
			var all = all(true);
			if (all == null || all.isEmpty())
				return null;
			return all.get(all.size() - 1).id;
		}

		public Commit latest() {
			var all = all(true);
			if (all == null || all.isEmpty())
				return null;
			return all.get(all.size() - 1);
		}

		public List all() {
			return all(false);
		}

		private List all(boolean singleResult) {
			var commits = new LinkedHashSet();
			try (var walk = walk()) {
				for (var commit : walk) {
					var commitId = commit.getId().name();
					if (!includeEnd && end != null && commitId.equals(end))
						continue;
					commits.add(new Commit(commit));
					if (singleResult)
						return new ArrayList<>(commits);
				}
				if (includeStart && start != null) {
					var commit = repo.parseCommit(toObjectId(start));
					commits.add(new Commit(commit));
				}
			} catch (IOException | GitAPIException e) {
				log.error("Error accessing history", e);
			}
			var list = new ArrayList<>(commits);
			Collections.reverse(list);
			return list;
		}

		private RevWalk walk() throws IOException, GitAPIException {
			var startId = toObjectId(start);
			var endId = toObjectId(end);
			var walk = new RevWalk(repo);
			if (endId == null && !repo.getRefDatabase().hasRefs())
				return walk;
			if (endId != null) {
				walk.markStart(walk.lookupCommit(endId));
			} else {
				for (var ref : repo.getRefDatabase().getRefs()) {
					if (branches.isEmpty() || branches.contains(ref.getName())) {
						var id = ref.getObjectId();
						if (startId != null && startId.equals(id))
							continue;
						walk.markStart(walk.parseCommit(id));
					}
				}
			}
			if (startId != null) {
				walk.markUninteresting(walk.parseCommit(startId));
			}
			TreeFilter filter = null;
			if (!Strings.nullOrEmpty(path)) {
				filter = addFilter(filter, PathFilter.create(GitUtil.encode(path)));
			}
			if (type != null && !Strings.nullOrEmpty(refId)) {
				filter = addFilter(filter, new ModelFilter(type, refId));
			}
			if (filter != null) {
				filter = addFilter(filter, TreeFilter.ANY_DIFF);
				walk.setTreeFilter(filter);
			}
			return walk;
		}

		private TreeFilter addFilter(TreeFilter current, TreeFilter newFilter) {
			return current != null ? AndTreeFilter.create(current, newFilter) : newFilter;
		}

		private ObjectId toObjectId(String value) {
			if (value == null)
				return null;
			return ObjectId.fromString(value);
		}

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy