import org.eclipse.jgit.lib.ObjectIdRef;
import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.transport.RefSpec.WildcardMode;
import org.junit.Test;
public class RefSpecTest {
RefSpec a = new RefSpec("refs/heads/*:refs/remotes/origin/*");
a.setDestination("refs/remotes/origin/*/*");
}
+
+ @Test
+ public void sourceOnlywithWildcard() {
+ RefSpec a = new RefSpec("refs/heads/*",
+ WildcardMode.ALLOW_MISMATCH);
+ assertTrue(a.matchSource("refs/heads/master"));
+ assertNull(a.getDestination());
+ }
+
+ @Test
+ public void destinationWithWildcard() {
+ RefSpec a = new RefSpec("refs/heads/master:refs/heads/*",
+ WildcardMode.ALLOW_MISMATCH);
+ assertTrue(a.matchSource("refs/heads/master"));
+ assertTrue(a.matchDestination("refs/heads/master"));
+ assertTrue(a.matchDestination("refs/heads/foo"));
+ }
+
+ @Test
+ public void onlyWildCard() {
+ RefSpec a = new RefSpec("*", WildcardMode.ALLOW_MISMATCH);
+ assertTrue(a.matchSource("refs/heads/master"));
+ assertNull(a.getDestination());
+ }
}
/** 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;
wildcard = false;
srcName = Constants.HEAD;
dstName = null;
+ allowMismatchedWildcards = WildcardMode.REQUIRE_MATCH;
}
/**
* <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;
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);
// 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;
}
/**
* @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;
}
* @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());
* @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;
}
* @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());
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);