DescribeCommand: use glob match instead of path match

Otherwise tags may fail to match if their name contains slashes.
Canonical git also uses its wildcard matcher in glob mode.[1]

[1] https://github.com/git/git/blob/v2.21.0/builtin/describe.c#L182

Bug: 546703
Change-Id: I122c7959974fa1fc6a53dfc65837e4314a8badd4
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
This commit is contained in:
Thomas Wolf 2019-04-30 19:11:16 +02:00 committed by Matthias Sohn
parent d2600693bd
commit 10ab407fa6
2 changed files with 28 additions and 6 deletions

View File

@ -421,6 +421,23 @@ public void t1sameDepthT2() throws Exception {
}
}
@Test
public void globMatchWithSlashes() throws Exception {
ObjectId c1 = modify("aaa");
tag("a/b/version");
ObjectId c2 = modify("bbb");
tag("a/b/version2");
if (useAnnotatedTags || describeUseAllTags) {
assertEquals("a/b/version", describe(c1, "*/version*"));
assertEquals("a/b/version2", describe(c2, "*/version*"));
} else {
assertNull(describe(c1));
assertNull(describe(c1, "*/version*"));
assertNull(describe(c2));
assertNull(describe(c2, "*/version*"));
}
}
private ObjectId merge(ObjectId c2) throws GitAPIException {
return git.merge().include(c2).call().getNewHead();
}

View File

@ -63,8 +63,7 @@
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.fnmatch.FileNameMatcher;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
@ -104,7 +103,7 @@ public class DescribeCommand extends GitCommand<String> {
/**
* Pattern matchers to be applied to tags under consideration.
*/
private List<IMatcher> matchers = new ArrayList<>();
private List<FileNameMatcher> matchers = new ArrayList<>();
/**
* Whether to use all tags (incl. lightweight) or not.
@ -242,7 +241,7 @@ private String longDescription(Ref tag, int depth, ObjectId tip)
*/
public DescribeCommand setMatch(String... patterns) throws InvalidPatternException {
for (String p : patterns) {
matchers.add(PathMatcher.createPathMatcher(p, null, false));
matchers.add(new FileNameMatcher(p, null));
}
return this;
}
@ -275,9 +274,15 @@ private Optional<Ref> getBestMatch(List<Ref> tags) {
// 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) {
for (FileNameMatcher matcher : matchers) {
Stream<Ref> m = tags.stream().filter(
tag -> matcher.matches(tag.getName(), false, false));
tag -> {
matcher.append(
tag.getName().substring(R_TAGS.length()));
boolean result = matcher.isMatch();
matcher.reset();
return result;
});
matchingTags = Stream.of(matchingTags, m).flatMap(i -> i);
}
return matchingTags.sorted(TAG_TIE_BREAKER).findFirst();