From af0867cb86a3b10ab3851245fb148a817201e6ca Mon Sep 17 00:00:00 2001 From: Oliver Lockwood Date: Fri, 16 Jun 2017 15:28:26 +0100 Subject: [PATCH] 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 Signed-off-by: Matthias Sohn --- .../eclipse/jgit/api/DescribeCommandTest.java | 36 ++++++++++---- .../org/eclipse/jgit/api/DescribeCommand.java | 47 +++++++++++++++++-- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java index 1e5d3bc30..ff9ae596c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java @@ -54,6 +54,7 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.RefNotFoundException; +import org.eclipse.jgit.errors.InvalidPatternException; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.ObjectId; import org.junit.Test; @@ -92,26 +93,41 @@ public void testDescribe() throws Exception { ObjectId c1 = modify("aaa"); ObjectId c2 = modify("bbb"); - tag("t1"); + tag("alice-t1"); ObjectId c3 = modify("ccc"); - tag("t2"); + tag("bob-t2"); ObjectId c4 = modify("ddd"); assertNull(describe(c1)); assertNull(describe(c1, true)); - assertEquals("t1", describe(c2)); - assertEquals("t2", describe(c3)); - assertEquals("t2-0-g44579eb", describe(c3, true)); + assertNull(describe(c1, "a*", "b*", "c*")); + + 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"); // the value verified with git-describe(1) - assertEquals("t2-1-g3e563c5", describe(c4)); - assertEquals("t2-1-g3e563c5", describe(c4, true)); + assertEquals("bob-t2-1-g3e563c5", describe(c4)); + 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 - assertEquals("t2-1-g3e563c5", git.describe().call()); + assertEquals("bob-t2-1-g3e563c5", git.describe().call()); } /** @@ -271,6 +287,10 @@ private String describe(ObjectId c1) throws GitAPIException, IOException { 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) { assertTrue(c4.name(), c4.name().startsWith(prefix)); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java index 389c511e1..1353bf11a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java @@ -57,7 +57,10 @@ import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.InvalidPatternException; 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.lib.Constants; import org.eclipse.jgit.lib.ObjectId; @@ -93,6 +96,11 @@ public class DescribeCommand extends GitCommand { */ private boolean longDesc; + /** + * Pattern matchers to be applied to tags under consideration + */ + private List matchers = new ArrayList<>(); + /** * * @param repo @@ -169,6 +177,37 @@ private String longDescription(Ref tag, int depth, ObjectId tip) .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 Git documentation about describe + * @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 * set explicitly. @@ -243,9 +282,9 @@ String describe(ObjectId tip) throws IOException { List candidates = new ArrayList<>(); // all the candidates we find // is the target already pointing to a tag? if so, we are done! - Ref lucky = tags.get(target); - if (lucky != null) { - return longDesc ? longDescription(lucky, 0, target) : lucky + Ref tagOnTarget = tags.get(target); + if (tagMatches(tagOnTarget)) { + return longDesc ? longDescription(tagOnTarget, 0, target) : tagOnTarget .getName().substring(R_TAGS.length()); } @@ -259,7 +298,7 @@ String describe(ObjectId tip) throws IOException { // then there's no point in picking a tag on this commit // since the one that dominates it is always more preferable Ref t = tags.get(c); - if (t != null) { + if (tagMatches(t)) { Candidate cd = new Candidate(c, t); candidates.add(cd); cd.depth = seen;