@ -82,6 +82,12 @@ public class RefSpec implements Serializable {
/** Is this specification actually a wildcard match? */
private boolean wildcard ;
enum WildcardMode {
REQUIRE_MATCH , ALLOW_MISMATCH
}
/** Whether a wildcard is allowed on one side but not the other. */
private WildcardMode allowMismatchedWildcards ;
/** Name of the ref(s) we would copy from. */
private String srcName ;
@ -99,6 +105,7 @@ public class RefSpec implements Serializable {
wildcard = false ;
srcName = Constants . HEAD ;
dstName = null ;
allowMismatchedWildcards = WildcardMode . REQUIRE_MATCH ;
}
/ * *
@ -116,12 +123,24 @@ public class RefSpec implements Serializable {
* < li > < code > : refs / heads / master < / code > < / li >
* < / ul >
*
* If the wildcard mode allows mismatches , then these ref specs are also
* valid :
* < ul >
* < li > < code > refs / heads / * < / code > < / li >
* < li > < code > refs / heads / * : refs / heads / master < / code > < / li >
* < / ul >
*
* @param spec
* string describing the specification .
* @param mode
* whether to allow a wildcard on one side without a wildcard on
* the other .
* @throws IllegalArgumentException
* the specification is invalid .
* @since 4 . 5
* /
public RefSpec ( final String spec ) {
public RefSpec ( String spec , WildcardMode mode ) {
this . allowMismatchedWildcards = mode ;
String s = spec ;
if ( s . startsWith ( "+" ) ) { //$NON-NLS-1$
force = true ;
@ -131,8 +150,13 @@ public class RefSpec implements Serializable {
final int c = s . lastIndexOf ( ':' ) ;
if ( c = = 0 ) {
s = s . substring ( 1 ) ;
if ( isWildcard ( s ) )
throw new IllegalArgumentException ( MessageFormat . format ( JGitText . get ( ) . invalidWildcards , spec ) ) ;
if ( isWildcard ( s ) ) {
wildcard = true ;
if ( mode = = WildcardMode . REQUIRE_MATCH ) {
throw new IllegalArgumentException ( MessageFormat
. format ( JGitText . get ( ) . invalidWildcards , spec ) ) ;
}
}
dstName = checkValid ( s ) ;
} else if ( c > 0 ) {
String src = s . substring ( 0 , c ) ;
@ -141,24 +165,55 @@ public class RefSpec implements Serializable {
// Both contain wildcard
wildcard = true ;
} else if ( isWildcard ( src ) | | isWildcard ( dst ) ) {
// If either source or destination has wildcard, the other one
// must have as well.
throw new IllegalArgumentException ( MessageFormat . format ( JGitText . get ( ) . invalidWildcards , spec ) ) ;
wildcard = true ;
if ( mode = = WildcardMode . REQUIRE_MATCH )
throw new IllegalArgumentException ( MessageFormat
. format ( JGitText . get ( ) . invalidWildcards , spec ) ) ;
}
srcName = checkValid ( src ) ;
dstName = checkValid ( dst ) ;
} else {
if ( isWildcard ( s ) )
throw new IllegalArgumentException ( MessageFormat . format ( JGitText . get ( ) . invalidWildcards , spec ) ) ;
if ( isWildcard ( s ) ) {
if ( mode = = WildcardMode . REQUIRE_MATCH ) {
throw new IllegalArgumentException ( MessageFormat
. format ( JGitText . get ( ) . invalidWildcards , spec ) ) ;
}
wildcard = true ;
}
srcName = checkValid ( s ) ;
}
}
/ * *
* Parse a ref specification for use during transport operations .
* < p >
* Specifications are typically one of the following forms :
* < ul >
* < li > < code > refs / heads / master < / code > < / li >
* < li > < code > refs / heads / master : refs / remotes / origin / master < / code > < / li >
* < li > < code > refs / heads / * : refs / remotes / origin / * < / code > < / li >
* < li > < code > + refs / heads / master < / code > < / li >
* < li > < code > + refs / heads / master : refs / remotes / origin / master < / code > < / li >
* < li > < code > + refs / heads / * : refs / remotes / origin / * < / code > < / li >
* < li > < code > + refs / pull / & # 42 ; / head : refs / remotes / origin / pr / * < / code > < / li >
* < li > < code > : refs / heads / master < / code > < / li >
* < / ul >
*
* @param spec
* string describing the specification .
* @throws IllegalArgumentException
* the specification is invalid .
* /
public RefSpec ( final String spec ) {
this ( spec , WildcardMode . REQUIRE_MATCH ) ;
}
private RefSpec ( final RefSpec p ) {
force = p . isForceUpdate ( ) ;
wildcard = p . isWildcard ( ) ;
srcName = p . getSource ( ) ;
dstName = p . getDestination ( ) ;
allowMismatchedWildcards = p . allowMismatchedWildcards ;
}
/ * *
@ -348,8 +403,15 @@ public class RefSpec implements Serializable {
* @return a new specification expanded from provided ref name . Result
* specification is wildcard if and only if provided ref name is
* wildcard .
* @throws IllegalStateException
* when the RefSpec was constructed with wildcard mode that
* doesn ' t require matching wildcards .
* /
public RefSpec expandFromSource ( final String r ) {
if ( allowMismatchedWildcards ! = WildcardMode . REQUIRE_MATCH ) {
throw new IllegalStateException (
JGitText . get ( ) . invalidExpandWildcard ) ;
}
return isWildcard ( ) ? new RefSpec ( this ) . expandFromSourceImp ( r ) : this ;
}
@ -373,6 +435,9 @@ public class RefSpec implements Serializable {
* @return a new specification expanded from provided ref name . Result
* specification is wildcard if and only if provided ref name is
* wildcard .
* @throws IllegalStateException
* when the RefSpec was constructed with wildcard mode that
* doesn ' t require matching wildcards .
* /
public RefSpec expandFromSource ( final Ref r ) {
return expandFromSource ( r . getName ( ) ) ;
@ -390,8 +455,15 @@ public class RefSpec implements Serializable {
* @return a new specification expanded from provided ref name . Result
* specification is wildcard if and only if provided ref name is
* wildcard .
* @throws IllegalStateException
* when the RefSpec was constructed with wildcard mode that
* doesn ' t require matching wildcards .
* /
public RefSpec expandFromDestination ( final String r ) {
if ( allowMismatchedWildcards ! = WildcardMode . REQUIRE_MATCH ) {
throw new IllegalStateException (
JGitText . get ( ) . invalidExpandWildcard ) ;
}
return isWildcard ( ) ? new RefSpec ( this ) . expandFromDstImp ( r ) : this ;
}
@ -414,6 +486,9 @@ public class RefSpec implements Serializable {
* @return a new specification expanded from provided ref name . Result
* specification is wildcard if and only if provided ref name is
* wildcard .
* @throws IllegalStateException
* when the RefSpec was constructed with wildcard mode that
* doesn ' t require matching wildcards .
* /
public RefSpec expandFromDestination ( final Ref r ) {
return expandFromDestination ( r . getName ( ) ) ;
@ -422,7 +497,7 @@ public class RefSpec implements Serializable {
private boolean match ( final String name , final String s ) {
if ( s = = null )
return false ;
if ( isWildcard ( ) ) {
if ( isWildcard ( s ) ) {
int wildcardIndex = s . indexOf ( '*' ) ;
String prefix = s . substring ( 0 , wildcardIndex ) ;
String suffix = s . substring ( wildcardIndex + 1 ) ;