@ -1,6 +1,7 @@
/ *
/ *
* Copyright ( C ) 2010 , Mathias Kinzler < mathias . kinzler @sap.com >
* Copyright ( C ) 2010 , Mathias Kinzler < mathias . kinzler @sap.com >
* Copyright ( C ) 2010 , Chris Aniszczyk < caniszczyk @gmail.com >
* Copyright ( C ) 2010 , Chris Aniszczyk < caniszczyk @gmail.com >
* Copyright ( C ) 2014 , Robin Stocker < robin @nibor.org >
* and other copyright owners as documented in the project ' s IP log .
* and other copyright owners as documented in the project ' s IP log .
*
*
* This program and the accompanying materials are made available
* This program and the accompanying materials are made available
@ -44,21 +45,30 @@
package org.eclipse.jgit.api ;
package org.eclipse.jgit.api ;
import java.io.IOException ;
import java.io.IOException ;
import java.text.MessageFormat ;
import java.util.ArrayList ;
import java.util.ArrayList ;
import java.util.Collection ;
import java.util.Collections ;
import java.util.Collections ;
import java.util.Comparator ;
import java.util.Comparator ;
import java.util.HashMap ;
import java.util.List ;
import java.util.List ;
import java.util.Map ;
import org.eclipse.jgit.api.errors.GitAPIException ;
import org.eclipse.jgit.api.errors.GitAPIException ;
import org.eclipse.jgit.api.errors.JGitInternalException ;
import org.eclipse.jgit.api.errors.JGitInternalException ;
import org.eclipse.jgit.api.errors.RefNotFoundException ;
import org.eclipse.jgit.internal.JGitText ;
import org.eclipse.jgit.lib.Constants ;
import org.eclipse.jgit.lib.Constants ;
import org.eclipse.jgit.lib.ObjectId ;
import org.eclipse.jgit.lib.Ref ;
import org.eclipse.jgit.lib.Ref ;
import org.eclipse.jgit.lib.Repository ;
import org.eclipse.jgit.lib.Repository ;
import org.eclipse.jgit.revwalk.RevCommit ;
import org.eclipse.jgit.revwalk.RevWalk ;
import org.eclipse.jgit.revwalk.RevWalkUtils ;
/ * *
/ * *
* Used to obtain a list of branches .
* Used to obtain a list of branches .
* < p >
* In case HEAD is detached ( it points directly to a commit ) , it is also
* returned in the results .
*
*
* @see < a
* @see < a
* href = "http://www.kernel.org/pub/software/scm/git/docs/git-branch.html"
* href = "http://www.kernel.org/pub/software/scm/git/docs/git-branch.html"
@ -67,6 +77,8 @@ import org.eclipse.jgit.lib.Repository;
public class ListBranchCommand extends GitCommand < List < Ref > > {
public class ListBranchCommand extends GitCommand < List < Ref > > {
private ListMode listMode ;
private ListMode listMode ;
private String containsCommitish ;
/ * *
/ * *
* The modes available for listing branches ( corresponding to the - r and - a
* The modes available for listing branches ( corresponding to the - r and - a
* options )
* options )
@ -91,23 +103,28 @@ public class ListBranchCommand extends GitCommand<List<Ref>> {
public List < Ref > call ( ) throws GitAPIException {
public List < Ref > call ( ) throws GitAPIException {
checkCallable ( ) ;
checkCallable ( ) ;
Map < String , Ref > refLi st ;
List < Ref > resultRe fs ;
try {
try {
Collection < Ref > refs = new ArrayList < Ref > ( ) ;
// Also return HEAD if it's detached
Ref head = repo . getRef ( Constants . HEAD ) ;
if ( head ! = null & & head . getLeaf ( ) . getName ( ) . equals ( Constants . HEAD ) )
refs . add ( head ) ;
if ( listMode = = null ) {
if ( listMode = = null ) {
refList = repo . getRefDatabase ( ) . getRefs ( Constants . R_HEADS ) ;
refs . addAll ( getRefs ( Constants . R_HEADS ) ) ;
} else if ( listMode = = ListMode . REMOTE ) {
} else if ( listMode = = ListMode . REMOTE ) {
refList = repo . getRefDatabase ( ) . getRefs ( Constants . R_REMOTES ) ;
refs . addAll ( getRefs ( Constants . R_REMOTES ) ) ;
} else {
} else {
refList = new HashMap < String , Ref > ( repo . getRefDatabase ( ) . getRefs (
refs . addAll ( getRefs ( Constants . R_HEADS ) ) ;
Constants . R_HEADS ) ) ;
refs . addAll ( getRefs ( Constants . R_REMOTES ) ) ;
refList . putAll ( repo . getRefDatabase ( ) . getRefs (
Constants . R_REMOTES ) ) ;
}
}
resultRefs = new ArrayList < Ref > ( filterRefs ( refs ) ) ;
} catch ( IOException e ) {
} catch ( IOException e ) {
throw new JGitInternalException ( e . getMessage ( ) , e ) ;
throw new JGitInternalException ( e . getMessage ( ) , e ) ;
}
}
List < Ref > resultRefs = new ArrayList < Ref > ( ) ;
resultRefs . addAll ( refList . values ( ) ) ;
Collections . sort ( resultRefs , new Comparator < Ref > ( ) {
Collections . sort ( resultRefs , new Comparator < Ref > ( ) {
public int compare ( Ref o1 , Ref o2 ) {
public int compare ( Ref o1 , Ref o2 ) {
return o1 . getName ( ) . compareTo ( o2 . getName ( ) ) ;
return o1 . getName ( ) . compareTo ( o2 . getName ( ) ) ;
@ -117,6 +134,26 @@ public class ListBranchCommand extends GitCommand<List<Ref>> {
return resultRefs ;
return resultRefs ;
}
}
private Collection < Ref > filterRefs ( Collection < Ref > refs )
throws RefNotFoundException , IOException {
if ( containsCommitish = = null )
return refs ;
RevWalk walk = new RevWalk ( repo ) ;
try {
ObjectId resolved = repo . resolve ( containsCommitish ) ;
if ( resolved = = null )
throw new RefNotFoundException ( MessageFormat . format (
JGitText . get ( ) . refNotResolved , containsCommitish ) ) ;
RevCommit containsCommit = walk . parseCommit ( resolved ) ;
return RevWalkUtils . findBranchesReachableFrom ( containsCommit , walk ,
refs ) ;
} finally {
walk . release ( ) ;
}
}
/ * *
/ * *
* @param listMode
* @param listMode
* optional : corresponds to the - r / - a options ; by default , only
* optional : corresponds to the - r / - a options ; by default , only
@ -128,4 +165,23 @@ public class ListBranchCommand extends GitCommand<List<Ref>> {
this . listMode = listMode ;
this . listMode = listMode ;
return this ;
return this ;
}
}
/ * *
* If this is set , only the branches that contain the specified commit - ish
* as an ancestor are returned .
*
* @param containsCommitish
* a commit ID or ref name
* @return this instance
* @since 3 . 3
* /
public ListBranchCommand setContains ( String containsCommitish ) {
checkCallable ( ) ;
this . containsCommitish = containsCommitish ;
return this ;
}
private Collection < Ref > getRefs ( String prefix ) throws IOException {
return repo . getRefDatabase ( ) . getRefs ( prefix ) . values ( ) ;
}
}
}