package hudson.plugins.git.util; import hudson.model.TaskListener; import hudson.plugins.git.Branch; import hudson.plugins.git.GitException; import hudson.plugins.git.IGitAPI; import hudson.plugins.git.IndexEntry; import hudson.plugins.git.Revision; import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.spearce.jgit.lib.ObjectId; public class GitUtils { IGitAPI git; TaskListener listener; public GitUtils(TaskListener listener, IGitAPI git) { this.git = git; this.listener = listener; } public List<IndexEntry> getSubmodules(String treeIsh) { List<IndexEntry> submodules = git.lsTree(treeIsh); // Remove anything that isn't a submodule for (Iterator<IndexEntry> it = submodules.iterator(); it.hasNext();) { if (!it.next().getMode().equals("160000")) { it.remove(); } } return submodules; } /** * Return a list of "Revisions" - where a revision knows about all the branch names that refer to * a SHA1. * @return * @throws IOException * @throws GitException */ public Collection<Revision> getAllBranchRevisions() throws GitException, IOException { Map<ObjectId, Revision> revisions = new HashMap<ObjectId, Revision>(); List<Branch> branches = git.getRemoteBranches(); for (Branch b : branches) { Revision r = revisions.get(b.getSHA1()); if (r == null) { r = new Revision(b.getSHA1()); revisions.put(b.getSHA1(), r); } r.getBranches().add(b); } return revisions.values(); } /** * Return the revision containing the branch name. * @param branchName * @return * @throws IOException * @throws GitException */ public Revision getRevisionContainingBranch(String branchName) throws GitException, IOException { for(Revision revision : getAllBranchRevisions() ) { for(Branch b : revision.getBranches()) { if( b.getName().equals(branchName) ) { return revision; } } } return null; } public Revision getRevisionForSHA1(ObjectId sha1) throws GitException, IOException { for(Revision revision : getAllBranchRevisions() ) { if( revision.getSha1().equals(sha1) ) return revision; } return null; } /** * Return a list of 'tip' branches (I.E. branches that aren't included entirely within another branch). * * @param git * @return */ public Collection<Revision> filterTipBranches(Collection<Revision> revisions) { // If we have 3 branches that we might want to build // ----A--.---.--- B // \-----C // we only want (B) and (C), as (A) is an ancestor (old). for (Iterator<Revision> it = revisions.iterator(); it.hasNext();) { Revision r = it.next(); boolean remove = false; for (Revision r2 : revisions) { if (r != r2) { ObjectId commonAncestor = git.mergeBase(r.getSha1(), r2.getSha1()); if (commonAncestor != null && commonAncestor.equals(r.getSha1())) { remove = true; break; } } } if (remove) it.remove(); } return revisions; } public static String[] fixupNames(String[] names, String[] urls) { String[] returnNames = new String[urls.length]; Set<String> usedNames = new HashSet<String>(); for(int i=0; i<urls.length; i++ ) { String name = names[i]; if( name == null || name.trim().length() == 0 ) { name = "origin"; } String baseName = name; int j=1; while(usedNames.contains(name)) { name = baseName + (j++); } usedNames.add(name); returnNames[i] = name; } return returnNames; } }