|
|
@@ -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/*/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); |