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

org.gitective.core.CommitUtils Maven / Gradle / Ivy

/*
 * Copyright (c) 2011 Kevin Sawicki 
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
package org.gitective.core;

import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.eclipse.jgit.lib.Constants.MASTER;
import static org.eclipse.jgit.lib.Constants.R_HEADS;
import static org.eclipse.jgit.lib.Constants.R_REMOTES;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
import static org.eclipse.jgit.revwalk.filter.RevFilter.MERGE_BASE;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashSet;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;

/**
 * Utilities for dealing with Git commits.
 * 

* This class provides helpers for finding the commits that branches and tags * reference. */ public abstract class CommitUtils { /** * Get the commit that the revision references. * * @param repository * @param revision * @return commit */ public static RevCommit getCommit(final Repository repository, final String revision) { if (repository == null) throw new IllegalArgumentException( Assert.formatNotNull("Repository")); if (revision == null) throw new IllegalArgumentException(Assert.formatNotNull("Revision")); if (revision.length() == 0) throw new IllegalArgumentException( Assert.formatNotEmpty("Revision")); ObjectId commitId = resolve(repository, revision); if (commitId == null) { return null; } return parse(repository, commitId); } /** * Get the commit with the given id * * @param repository * @param commitId * @return commit */ public static RevCommit getCommit(final Repository repository, final ObjectId commitId) { if (repository == null) throw new IllegalArgumentException( Assert.formatNotNull("Repository")); if (commitId == null) throw new IllegalArgumentException( Assert.formatNotNull("Commit id")); return parse(repository, commitId); } /** * Get the HEAD commit in the given repository. * * @param repository * @return commit never null */ public static RevCommit getHead(final Repository repository) { return getCommit(repository, HEAD); } /** * Get the commit at the tip of the master branch in the given repository. * * @param repository * @return commit never null */ public static RevCommit getMaster(final Repository repository) { return getCommit(repository, MASTER); } /** * Get the common base commit of the given commits. * * @param repository * @param commits * @return base commit or null if none */ public static RevCommit getBase(final Repository repository, final ObjectId... commits) { if (repository == null) throw new IllegalArgumentException( Assert.formatNotNull("Repository")); if (commits == null) throw new IllegalArgumentException(Assert.formatNotNull("Commits")); if (commits.length == 0) throw new IllegalArgumentException(Assert.formatNotEmpty("Commits")); return walkToBase(repository, commits); } /** * Get the common base commit between the given revisions. * * @param repository * @param revisions * @return base commit or null if none */ public static RevCommit getBase(final Repository repository, final String... revisions) { if (repository == null) throw new IllegalArgumentException( Assert.formatNotNull("Repository")); if (revisions == null) throw new IllegalArgumentException( Assert.formatNotNull("Revisions")); if (revisions.length == 0) throw new IllegalArgumentException( Assert.formatNotEmpty("Revisions")); final int length = revisions.length; final ObjectId[] commits = new ObjectId[length]; for (int i = 0; i < length; i++) { commits[i] = strictResolve(repository, revisions[i]); } return walkToBase(repository, commits); } /** * Get the commit that the given name references. * * @param repository * @param refName * @return commit, may be null */ public static RevCommit getRef(final Repository repository, final String refName) { if (repository == null) throw new IllegalArgumentException( Assert.formatNotNull("Repository")); if (refName == null) throw new IllegalArgumentException(Assert.formatNotNull("Ref name")); if (refName.length() == 0) throw new IllegalArgumentException( Assert.formatNotEmpty("Ref name")); Ref ref; ref = repository.getAllRefs().get(refName); return ref != null ? lookupRef(repository, ref) : null; } /** * Get the commit for the given reference. * * @param repository * @param ref * @return commit, may be null */ public static RevCommit getRef(final Repository repository, final Ref ref) { if (repository == null) throw new IllegalArgumentException( Assert.formatNotNull("Repository")); if (ref == null) throw new IllegalArgumentException(Assert.formatNotNull("Ref")); return lookupRef(repository, ref); } /** * Get all the commits that tags in the given repository reference. * * @param repository * @return non-null but possibly empty collection of commits */ public static Collection getTags(final Repository repository) { if (repository == null) throw new IllegalArgumentException( Assert.formatNotNull("Repository")); final Collection commits = new HashSet(); final RevWalk walk = new RevWalk(repository); final RefDatabase refDb = repository.getRefDatabase(); try { getRefCommits(walk, refDb, R_TAGS, commits); } catch (IOException e) { throw new GitException(e, repository); } finally { walk.close(); } return commits; } /** * Get all the commits that branches in the given repository reference. * * @param repository * @return non-null but possibly empty collection of commits */ public static Collection getBranches(final Repository repository) { if (repository == null) throw new IllegalArgumentException( Assert.formatNotNull("Repository")); final Collection commits = new HashSet(); final RevWalk walk = new RevWalk(repository); final RefDatabase refDb = repository.getRefDatabase(); try { getRefCommits(walk, refDb, R_HEADS, commits); getRefCommits(walk, refDb, R_REMOTES, commits); } catch (IOException e) { throw new GitException(e, repository); } finally { walk.close(); } return commits; } private static void getRefCommits(final RevWalk walk, final RefDatabase refDb, final String prefix, final Collection commits) throws IOException { for (Ref ref : refDb.getRefs(prefix).values()) { final RevCommit commit = getRef(walk, ref); if (commit != null) commits.add(commit); } } private static RevCommit lookupRef(final Repository repository, final Ref ref) { final RevWalk walk = new RevWalk(repository); try { return getRef(walk, ref); } catch (IOException e) { throw new GitException(e, repository); } finally { walk.close(); } } private static RevCommit getRef(final RevWalk walk, final Ref ref) throws IOException { ObjectId id = ref.getPeeledObjectId(); if (id == null) id = ref.getObjectId(); return id != null ? walk.parseCommit(id) : null; } /** * Resolve the revision string to a commit object id * * @param repository * @param revision * @return commit id */ protected static ObjectId resolve(final Repository repository, final String revision) { try { return repository.resolve(revision); } catch (IOException e) { throw new GitException(e, repository); } } /** * Resolve the revision string to a commit object id. *

* A {@link GitException} will be thrown when the revision can not be * resolved to an {@link ObjectId} * * @param repository * @param revision * @return commit id */ protected static ObjectId strictResolve(final Repository repository, final String revision) { final ObjectId resolved = resolve(repository, revision); if (resolved == null) throw new GitException(MessageFormat.format( "Revision ''{0}'' could not be resolved", revision), repository); return resolved; } private static RevCommit walkToBase(final Repository repository, final ObjectId... commits) { final RevWalk walk = new RevWalk(repository); walk.setRevFilter(MERGE_BASE); try { for (int i = 0; i < commits.length; i++) walk.markStart(walk.parseCommit(commits[i])); final RevCommit base = walk.next(); if (base != null) walk.parseBody(base); return base; } catch (IOException e) { throw new GitException(e, repository); } finally { walk.close(); } } /** * Parse a commit from the repository * * @param repository * @param commit * @return commit */ protected static RevCommit parse(final Repository repository, final ObjectId commit) { final RevWalk walk = new RevWalk(repository); walk.setRetainBody(true); try { return walk.parseCommit(commit); } catch (IOException e) { throw new GitException(e, repository); } finally { walk.close(); } } /** * Parse a commit from the object reader * * @param repository * @param reader * @param commit * @return commit */ protected static RevCommit parse(final Repository repository, final ObjectReader reader, final ObjectId commit) { final RevWalk walk = new RevWalk(reader); walk.setRetainBody(true); try { return walk.parseCommit(commit); } catch (IOException e) { throw new GitException(e, repository); } } /** * Find the commit that last changed the given path starting at the commit * that HEAD currently points to * * @param repository * @param path * @return commit */ public static RevCommit getLastCommit(final Repository repository, final String path) { return getLastCommit(repository, HEAD, path); } /** * Find the commit that last changed the given path starting with the commit * at the given revision * * @param repository * @param revision * @param path * @return commit */ public static RevCommit getLastCommit(final Repository repository, final String revision, final String path) { if (repository == null) throw new IllegalArgumentException( Assert.formatNotNull("Repository")); if (revision == null) throw new IllegalArgumentException(Assert.formatNotNull("Revision")); if (revision.length() == 0) throw new IllegalArgumentException( Assert.formatNotEmpty("Revision")); if (path == null) throw new IllegalArgumentException(Assert.formatNotNull("Path")); if (path.length() == 0) throw new IllegalArgumentException(Assert.formatNotEmpty("Path")); final RevWalk walk = new RevWalk(repository); walk.setRetainBody(true); try { walk.markStart(walk .parseCommit(strictResolve(repository, revision))); walk.setTreeFilter(PathFilterUtils.and(path)); return walk.next(); } catch (IOException e) { throw new GitException(e, repository); } finally { walk.close(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy