summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorRobin Stocker <robin@nibor.org>2013-05-04 16:43:51 +0200
committerGerrit Code Review @ Eclipse.org <gerrit@eclipse.org>2013-05-28 05:33:03 -0400
commita51899c2036984fa7a04290ca1364a02af34f95a (patch)
treea33c778e7e5345e813e3c905f9685033938fac7e /org.eclipse.jgit
parentec97912762754ee88f1af5ed80e993c545778242 (diff)
downloadjgit-a51899c2036984fa7a04290ca1364a02af34f95a.tar.gz
jgit-a51899c2036984fa7a04290ca1364a02af34f95a.zip
Support refspecs with wildcard in middle (not only at end)
The following refspec, which can be used to fetch GitHub pull requests, is supported by C Git but was not yet by JGit: +refs/pull/*/head:refs/remotes/origin/pr/* The reason is that the wildcard in the source is in the middle. This change also includes more validation (e.g. "refs//heads" is not valid) and test cases. Bug: 405099 Change-Id: I9bcef7785a0762ed0a98ca95a0bdf8879d5702aa
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java81
3 files changed, 64 insertions, 19 deletions
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 8b6211efbb..33489eb676 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -271,6 +271,7 @@ invalidTagOption=Invalid tag option: {0}
invalidTimeout=Invalid timeout: {0}
invalidURL=Invalid URL {0}
invalidWildcards=Invalid wildcards {0}
+invalidRefSpec=Invalid refspec {0}
invalidWindowSize=Invalid window size
isAStaticFlagAndHasNorevWalkInstance={0} is a static flag and has no RevWalk instance
JRELacksMD5Implementation=JRE lacks MD5 implementation
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index 29bec97ee7..d75ed4ee2a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -333,6 +333,7 @@ public class JGitText extends TranslationBundle {
/***/ public String invalidTimeout;
/***/ public String invalidURL;
/***/ public String invalidWildcards;
+ /***/ public String invalidRefSpec;
/***/ public String invalidWindowSize;
/***/ public String isAStaticFlagAndHasNorevWalkInstance;
/***/ public String JRELacksMD5Implementation;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
index 9b38b29336..66ffc3abe9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/RefSpec.java
@@ -43,8 +43,8 @@
package org.eclipse.jgit.transport;
-import java.text.MessageFormat;
import java.io.Serializable;
+import java.text.MessageFormat;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants;
@@ -59,7 +59,7 @@ import org.eclipse.jgit.lib.Ref;
public class RefSpec implements Serializable {
private static final long serialVersionUID = 1L;
- /**
+ /**
* Suffix for wildcard ref spec component, that indicate matching all refs
* with specified prefix.
*/
@@ -73,7 +73,7 @@ public class RefSpec implements Serializable {
* @return true if provided string is a wildcard ref spec component.
*/
public static boolean isWildcard(final String s) {
- return s != null && s.endsWith(WILDCARD_SUFFIX);
+ return s != null && s.contains("*"); //$NON-NLS-1$
}
/** Does this specification ask for forced updated (rewind/reset)? */
@@ -112,6 +112,7 @@ public class RefSpec implements Serializable {
* <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>
*
@@ -132,18 +133,24 @@ public class RefSpec implements Serializable {
s = s.substring(1);
if (isWildcard(s))
throw new IllegalArgumentException(MessageFormat.format(JGitText.get().invalidWildcards, spec));
- dstName = s;
+ dstName = checkValid(s);
} else if (c > 0) {
- srcName = s.substring(0, c);
- dstName = s.substring(c + 1);
- if (isWildcard(srcName) && isWildcard(dstName))
+ String src = s.substring(0, c);
+ String dst = s.substring(c + 1);
+ if (isWildcard(src) && isWildcard(dst)) {
+ // Both contain wildcard
wildcard = true;
- else if (isWildcard(srcName) || isWildcard(dstName))
+ } 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));
+ }
+ srcName = checkValid(src);
+ dstName = checkValid(dst);
} else {
if (isWildcard(s))
throw new IllegalArgumentException(MessageFormat.format(JGitText.get().invalidWildcards, spec));
- srcName = s;
+ srcName = checkValid(s);
}
}
@@ -215,7 +222,7 @@ public class RefSpec implements Serializable {
*/
public RefSpec setSource(final String source) {
final RefSpec r = new RefSpec(this);
- r.srcName = source;
+ r.srcName = checkValid(source);
if (isWildcard(r.srcName) && r.dstName == null)
throw new IllegalStateException(JGitText.get().destinationIsNotAWildcard);
if (isWildcard(r.srcName) != isWildcard(r.dstName))
@@ -254,7 +261,7 @@ public class RefSpec implements Serializable {
*/
public RefSpec setDestination(final String destination) {
final RefSpec r = new RefSpec(this);
- r.dstName = destination;
+ r.dstName = checkValid(destination);
if (isWildcard(r.dstName) && r.srcName == null)
throw new IllegalStateException(JGitText.get().sourceIsNotAWildcard);
if (isWildcard(r.srcName) != isWildcard(r.dstName))
@@ -350,8 +357,7 @@ public class RefSpec implements Serializable {
final String psrc = srcName, pdst = dstName;
wildcard = false;
srcName = name;
- dstName = pdst.substring(0, pdst.length() - 1)
- + name.substring(psrc.length() - 1);
+ dstName = expandWildcard(name, psrc, pdst);
return this;
}
@@ -392,8 +398,7 @@ public class RefSpec implements Serializable {
private RefSpec expandFromDstImp(final String name) {
final String psrc = srcName, pdst = dstName;
wildcard = false;
- srcName = psrc.substring(0, psrc.length() - 1)
- + name.substring(pdst.length() - 1);
+ srcName = expandWildcard(name, pdst, psrc);
dstName = name;
return this;
}
@@ -414,12 +419,50 @@ public class RefSpec implements Serializable {
return expandFromDestination(r.getName());
}
- private boolean match(final String refName, final String s) {
+ private boolean match(final String name, final String s) {
if (s == null)
return false;
- if (isWildcard())
- return refName.startsWith(s.substring(0, s.length() - 1));
- return refName.equals(s);
+ if (isWildcard()) {
+ int wildcardIndex = s.indexOf('*');
+ String prefix = s.substring(0, wildcardIndex);
+ String suffix = s.substring(wildcardIndex + 1);
+ return name.length() > prefix.length() + suffix.length()
+ && name.startsWith(prefix) && name.endsWith(suffix);
+ }
+ return name.equals(s);
+ }
+
+ private static String expandWildcard(String name, String patternA,
+ String patternB) {
+ int a = patternA.indexOf('*');
+ int trailingA = patternA.length() - (a + 1);
+ int b = patternB.indexOf('*');
+ String match = name.substring(a, name.length() - trailingA);
+ return patternB.substring(0, b) + match + patternB.substring(b + 1);
+ }
+
+ private static String checkValid(String spec) {
+ if (spec != null && !isValid(spec))
+ throw new IllegalArgumentException(MessageFormat.format(
+ JGitText.get().invalidRefSpec, spec));
+ return spec;
+ }
+
+ private static boolean isValid(final String s) {
+ if (s.startsWith("/")) //$NON-NLS-1$
+ return false;
+ if (s.contains("//")) //$NON-NLS-1$
+ return false;
+ int i = s.indexOf('*');
+ if (i != -1) {
+ if (s.indexOf('*', i + 1) > i)
+ return false;
+ if (i > 0 && s.charAt(i - 1) != '/')
+ return false;
+ if (i < s.length() - 1 && s.charAt(i + 1) != '/')
+ return false;
+ }
+ return true;
}
public int hashCode() {