128 lines
4.3 KiB
Java
128 lines
4.3 KiB
Java
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;
|
|
}
|
|
|
|
}
|