Commit bc550751 authored by Brian Long's avatar Brian Long
Browse files

split project between git/github

parent ef829b45
Loading
Loading
Loading
Loading
+0 −29
Original line number Diff line number Diff line
package me.brianlong.git;

import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.Repository;

public class CachedGit extends Git {
	
	public CachedGit(Git git) {
		super(git.getRepository());
	}
	
	public CachedGit(CloneCommand clone) throws TransportException, InvalidRemoteException, GitAPIException {
		super(clone.call().getRepository());
	}
	
	public CachedGit(Repository repo) {
		super(repo);
	}
	
	@Override
	public void close() {
		LocalRepositoryCache.getInstance().release(this);
	}

}
+0 −42
Original line number Diff line number Diff line
package me.brianlong.git;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;

public class CompositeIterator<E> implements Iterator<E> {
	
	private final List<Iterator<E>> iterators = new LinkedList<Iterator<E>>();
	private final Iterator<Iterator<E>> iteratorIterators;
	private Iterator<E> iterator;
	
	public CompositeIterator(@SuppressWarnings("unchecked") Collection<E>... cs) {
		for (Collection<E> c : cs)
			if (c != null && !c.isEmpty())
				this.iterators.add(c.iterator());
		this.iteratorIterators = this.iterators.iterator();
	}
	
	@Override
	public boolean hasNext() {
		if (this.iterator == null) {
			if (!this.iteratorIterators.hasNext())
				return false;
			this.iterator = this.iteratorIterators.next();
		}
		
		while (!this.iterator.hasNext() && this.iteratorIterators.hasNext())
			this.iterator = this.iteratorIterators.next();
		return this.iterator.hasNext();
	}
	
	@Override
	public E next() {
		if (!this.hasNext())
			throw new NoSuchElementException();
		return this.iterator.next();
	}

}
+0 −53
Original line number Diff line number Diff line
package me.brianlong.git;

import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.LsRemoteCommand;
import org.eclipse.jgit.api.PullCommand;
import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.CredentialsProvider;

public class CredentialedGit extends ExtendedGit {
	
	private CredentialsProvider credProvider;
	
	public CredentialedGit(CloneCommand clone, GitCredentials creds) throws TransportException, InvalidRemoteException, GitAPIException {
		this(clone.setCredentialsProvider(creds.toJGitCredentialsProvider()).call(), creds);
	}
	
	public CredentialedGit(Git git, GitCredentials creds) {
		super(git.getRepository());
		this.credProvider = creds.toJGitCredentialsProvider();
	}
	
	public CredentialedGit(Repository repo, GitCredentials creds) {
		super(repo);
		this.credProvider = creds.toJGitCredentialsProvider();
	}
	
	@Override
	public FetchCommand fetch() {
		return super.fetch().setCredentialsProvider(this.credProvider);
	}
	
	@Override
	public LsRemoteCommand lsRemote() {
		return super.lsRemote().setCredentialsProvider(this.credProvider);
	}
	
	@Override
	public PullCommand pull() {
		return super.pull().setCredentialsProvider(this.credProvider);
	}
	
	@Override
	public PushCommand push() {
		return super.push().setCredentialsProvider(this.credProvider);
	}

}
+0 −9
Original line number Diff line number Diff line
package me.brianlong.git;

import java.util.Map.Entry;

public interface ExpiringMapListener<K, V> extends MapListener<K, V> {
	
	void expired(Entry<K, V> entry);

}
+0 −127
Original line number Diff line number Diff line
package me.brianlong.git;

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListBranchCommand;
import org.eclipse.jgit.api.ListBranchCommand.ListMode;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExtendedGit extends CachedGit {
	
	private final Logger logger = LoggerFactory.getLogger(ExtendedGit.class);
	private final Pattern gitUrlPattern = Pattern.compile("(((ssh|http(s)?)://([^@]+@)?([^:/]+)(:[0-9]+)?/)|git@([^:]+):)([\\w\\.@\\:/\\-~]+)(\\.git)");
	
	public ExtendedGit(Git git) {
		super(git.getRepository());
	}
	
	public ExtendedGit(CloneCommand clone) throws TransportException, InvalidRemoteException, GitAPIException {
		super(clone.call().getRepository());
	}
	
	public ExtendedGit(Repository repo) {
		super(repo);
	}
	
	public String getFirstRemoteUrl() throws GitAPIException {
		return this.remoteList().call().iterator().next().getURIs().iterator().next().toString();
	}
	
	public String getRepositoryFullyQualifiedName() throws GitAPIException, URISyntaxException {
		String gitUrl = this.getFirstRemoteUrl();
		if (this.logger.isDebugEnabled())
			this.logger.debug("Remote URL: " + gitUrl);
		
		Matcher matcher = this.gitUrlPattern.matcher(gitUrl);
		if (!matcher.find())
			throw new URISyntaxException(gitUrl, "The Git URL does not match the expected regular expression: " + this.gitUrlPattern.toString());
		return matcher.group(9);
	}
	
	/**
	 * This method retrieves all branches, but excludes remote branches that are tracked with a local branch.
	 * @return
	 */
	public List<Ref> getAllUniqueBranches() throws GitAPIException {
		return this.getAllUniqueBranches(null);
	}
	
	/**
	 * This method retrieves all branches, but excludes remote branches that are tracked with a local branch.
	 * @return
	 */
	public List<Ref> getAllUniqueBranches(String containsCommitish) throws GitAPIException {
		ListBranchCommand command = this.branchList().setListMode(ListMode.ALL);
		if (containsCommitish != null)
			command.setContains(containsCommitish);
		List<Ref> branches = command.call();
		
		Set<String> abbrevBranchNames = new HashSet<String>(branches.size());
		List<Ref> trimmedBranches = new ArrayList<Ref>(branches.size());
		
		// sort them by local, then remote; keep order the same otherwise
		Collections.sort(branches, new Comparator<Ref>() {
			@Override
			public int compare(Ref o1, Ref o2) {
				if (o1 == null) return -1;
				else if (o2 == null) return 1;
				else {
					boolean o1local = o1.getName().startsWith(Constants.R_HEADS);
					boolean o2local = o2.getName().startsWith(Constants.R_HEADS);
					if (o1local && o2local) return 0;
					else if (o1local) return -1;
					else if (o2local) return 1;
					else return 0;
				}
			}
		});

		for (Ref branch : branches) {
			String fqBranchName = branch.getName();
			
			String abbrevBranchName = null;
			if (fqBranchName.startsWith(Constants.R_REMOTES)) {
				if (this.logger.isDebugEnabled())
					this.logger.debug("Ref is a remote branch: " + fqBranchName);
				abbrevBranchName = this.getRepository().shortenRemoteBranchName(fqBranchName);
			} else if (fqBranchName.startsWith(Constants.R_HEADS)) {
				if (this.logger.isDebugEnabled())
					this.logger.debug("Ref is a local branch: " + fqBranchName);
				abbrevBranchName = Repository.shortenRefName(fqBranchName);
			} else {
				if (this.logger.isDebugEnabled())
					this.logger.debug("Ref is not a local or remote branch: " + fqBranchName);
			}
			
			if (abbrevBranchName != null) {
				if (abbrevBranchNames.contains(abbrevBranchName)) {
					if (this.logger.isDebugEnabled())
						this.logger.debug("Branch already found; ignoring ...");
				} else {
					abbrevBranchNames.add(abbrevBranchName);
					trimmedBranches.add(branch);
				}
			}
		}
		
		return trimmedBranches;
	}

}
Loading