summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2018-11-25 23:15:11 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2018-11-26 18:49:30 +0100
commitdf6263644bb3387239cd77aa57074380610a0ec4 (patch)
tree45668ccf29c4149b3d2f7e338a59243737a3cbd9
parentf9de9175477577c6c7d0a22ebe5a1c9a1c299c1a (diff)
downloadjgit-df6263644bb3387239cd77aa57074380610a0ec4.tar.gz
jgit-df6263644bb3387239cd77aa57074380610a0ec4.zip
Fix DescribeCommand with multiple match options
when multiple match options are given in git describe the result must not depend on the order of the match options. JGit wrongly picked the first match using the match options in the order they were defined. Fix this by concatenating the streams of matching tags for all match options and then choosing the first match on the concatenated stream sorted in tie break order. See https://git-scm.com/docs/git-describe#git-describe---matchltpatterngt Change-Id: Id01433d35fa16fb4c30526605bee041ac1d954b2 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DescribeCommandTest.java4
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java18
2 files changed, 10 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 a2d8e89699..be67893cb9 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
@@ -156,9 +156,9 @@ public class DescribeCommandTest extends RepositoryTestCase {
assertEquals("v1.1.1-1-gb89dead", describe(c2, "v1.1*"));
// Ensure that ordering of match precedence is preserved as per Git behaviour
- assertEquals("v1.0.1", describe(c1, "v1.0*", "v1.1*"));
+ assertEquals("v1.1.1", describe(c1, "v1.0*", "v1.1*"));
assertEquals("v1.1.1", describe(c1, "v1.1*", "v1.0*"));
- assertEquals("v1.0.1-1-gb89dead", describe(c2, "v1.0*", "v1.1*"));
+ assertEquals("v1.1.1-1-gb89dead", describe(c2, "v1.0*", "v1.1*"));
assertEquals("v1.1.1-1-gb89dead", describe(c2, "v1.1*", "v1.0*"));
} else {
// no timestamps so no guarantees on which tag is chosen
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 18e8a7f4f9..5bd932d1cf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DescribeCommand.java
@@ -55,6 +55,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
@@ -230,18 +231,15 @@ public class DescribeCommand extends GitCommand<String> {
Collections.sort(tags, TAG_TIE_BREAKER);
return Optional.of(tags.get(0));
} else {
- // Find the first tag that matches one of the matchers; precedence according to matcher definition order
+ // Find the first tag that matches in the stream of all tags
+ // filtered by matchers ordered by tie break order
+ Stream<Ref> matchingTags = Stream.empty();
for (IMatcher matcher : matchers) {
- Optional<Ref> match = tags.stream()
- .filter(tag -> matcher.matches(tag.getName(), false,
- false))
- .sorted(TAG_TIE_BREAKER)
- .findFirst();
- if (match.isPresent()) {
- return match;
- }
+ Stream<Ref> m = tags.stream().filter(
+ tag -> matcher.matches(tag.getName(), false, false));
+ matchingTags = Stream.of(matchingTags, m).flatMap(i -> i);
}
- return Optional.empty();
+ return matchingTags.sorted(TAG_TIE_BREAKER).findFirst();
}
}