Browse Source

Support --match functionality in DescribeCommand

A `match()` method has been added to the DescribeCommand, allowing
users to specify one or more `glob(7)` matchers as per Git convention.

Bug: 518377
Change-Id: Ib4cf34ce58128eed0334adf6c4a052dbea62c601
Signed-off-by: Oliver Lockwood <oliver.lockwood@cantab.net>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
stable-4.9
Oliver Lockwood 8 years ago committed by Matthias Sohn
parent
commit
af0867cb86
  1. 36
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java
  2. 47
      org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java

36
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java

@ -54,6 +54,7 @@ import java.util.Collection;
import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.api.errors.RefNotFoundException;
import org.eclipse.jgit.errors.InvalidPatternException;
import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test; import org.junit.Test;
@ -92,26 +93,41 @@ public class DescribeCommandTest extends RepositoryTestCase {
ObjectId c1 = modify("aaa"); ObjectId c1 = modify("aaa");
ObjectId c2 = modify("bbb"); ObjectId c2 = modify("bbb");
tag("t1"); tag("alice-t1");
ObjectId c3 = modify("ccc"); ObjectId c3 = modify("ccc");
tag("t2"); tag("bob-t2");
ObjectId c4 = modify("ddd"); ObjectId c4 = modify("ddd");
assertNull(describe(c1)); assertNull(describe(c1));
assertNull(describe(c1, true)); assertNull(describe(c1, true));
assertEquals("t1", describe(c2)); assertNull(describe(c1, "a*", "b*", "c*"));
assertEquals("t2", describe(c3));
assertEquals("t2-0-g44579eb", describe(c3, true)); assertEquals("alice-t1", describe(c2));
assertEquals("alice-t1", describe(c2, "alice*"));
assertNull(describe(c2, "bob*"));
assertNull(describe(c2, "?ob*"));
assertEquals("alice-t1", describe(c2, "a*", "b*", "c*"));
assertEquals("bob-t2", describe(c3));
assertEquals("bob-t2-0-g44579eb", describe(c3, true));
assertEquals("alice-t1-1-g44579eb", describe(c3, "alice*"));
assertEquals("alice-t1-1-g44579eb", describe(c3, "a??c?-t*"));
assertEquals("bob-t2", describe(c3, "bob*"));
assertEquals("bob-t2", describe(c3, "?ob*"));
assertEquals("bob-t2", describe(c3, "a*", "b*", "c*"));
assertNameStartsWith(c4, "3e563c5"); assertNameStartsWith(c4, "3e563c5");
// the value verified with git-describe(1) // the value verified with git-describe(1)
assertEquals("t2-1-g3e563c5", describe(c4)); assertEquals("bob-t2-1-g3e563c5", describe(c4));
assertEquals("t2-1-g3e563c5", describe(c4, true)); assertEquals("bob-t2-1-g3e563c5", describe(c4, true));
assertEquals("alice-t1-2-g3e563c5", describe(c4, "alice*"));
assertEquals("bob-t2-1-g3e563c5", describe(c4, "bob*"));
assertEquals("bob-t2-1-g3e563c5", describe(c4, "a*", "b*", "c*"));
// test default target // test default target
assertEquals("t2-1-g3e563c5", git.describe().call()); assertEquals("bob-t2-1-g3e563c5", git.describe().call());
} }
/** /**
@ -271,6 +287,10 @@ public class DescribeCommandTest extends RepositoryTestCase {
return describe(c1, false); return describe(c1, false);
} }
private String describe(ObjectId c1, String... patterns) throws GitAPIException, IOException, InvalidPatternException {
return git.describe().setTarget(c1).setMatch(patterns).call();
}
private static void assertNameStartsWith(ObjectId c4, String prefix) { private static void assertNameStartsWith(ObjectId c4, String prefix) {
assertTrue(c4.name(), c4.name().startsWith(prefix)); assertTrue(c4.name(), c4.name().startsWith(prefix));
} }

47
org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java

@ -57,7 +57,10 @@ 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.api.errors.RefNotFoundException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.InvalidPatternException;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.ignore.internal.IMatcher;
import org.eclipse.jgit.ignore.internal.PathMatcher;
import org.eclipse.jgit.internal.JGitText; 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.ObjectId;
@ -93,6 +96,11 @@ public class DescribeCommand extends GitCommand<String> {
*/ */
private boolean longDesc; private boolean longDesc;
/**
* Pattern matchers to be applied to tags under consideration
*/
private List<IMatcher> matchers = new ArrayList<>();
/** /**
* *
* @param repo * @param repo
@ -169,6 +177,37 @@ public class DescribeCommand extends GitCommand<String> {
.name()); .name());
} }
/**
* Sets one or more {@code glob(7)} patterns that tags must match to be considered.
* If multiple patterns are provided, tags only need match one of them.
*
* @param patterns the {@code glob(7)} pattern or patterns
* @return {@code this}
* @throws InvalidPatternException if the pattern passed in was invalid.
*
* @see <a
* href="https://www.kernel.org/pub/software/scm/git/docs/git-describe.html"
* >Git documentation about describe</a>
* @since 4.9
*/
public DescribeCommand setMatch(String... patterns) throws InvalidPatternException {
for (String p : patterns) {
matchers.add(PathMatcher.createPathMatcher(p, null, false));
}
return this;
}
private boolean tagMatches(Ref tag) {
if (tag == null) {
return false;
} else if (matchers.size() == 0) {
return true;
} else {
return matchers.stream()
.anyMatch(m -> m.matches(tag.getName(), false));
}
}
/** /**
* Describes the specified commit. Target defaults to HEAD if no commit was * Describes the specified commit. Target defaults to HEAD if no commit was
* set explicitly. * set explicitly.
@ -243,9 +282,9 @@ public class DescribeCommand extends GitCommand<String> {
List<Candidate> candidates = new ArrayList<>(); // all the candidates we find List<Candidate> candidates = new ArrayList<>(); // all the candidates we find
// is the target already pointing to a tag? if so, we are done! // is the target already pointing to a tag? if so, we are done!
Ref lucky = tags.get(target); Ref tagOnTarget = tags.get(target);
if (lucky != null) { if (tagMatches(tagOnTarget)) {
return longDesc ? longDescription(lucky, 0, target) : lucky return longDesc ? longDescription(tagOnTarget, 0, target) : tagOnTarget
.getName().substring(R_TAGS.length()); .getName().substring(R_TAGS.length());
} }
@ -259,7 +298,7 @@ public class DescribeCommand extends GitCommand<String> {
// then there's no point in picking a tag on this commit // then there's no point in picking a tag on this commit
// since the one that dominates it is always more preferable // since the one that dominates it is always more preferable
Ref t = tags.get(c); Ref t = tags.get(c);
if (t != null) { if (tagMatches(t)) {
Candidate cd = new Candidate(c, t); Candidate cd = new Candidate(c, t);
candidates.add(cd); candidates.add(cd);
cd.depth = seen; cd.depth = seen;

Loading…
Cancel
Save