|
|
@@ -47,11 +47,13 @@ import static org.eclipse.jgit.lib.Constants.R_TAGS; |
|
|
|
import java.io.IOException; |
|
|
|
import java.text.MessageFormat; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Comparator; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Optional; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
import org.eclipse.jgit.api.errors.GitAPIException; |
|
|
|
import org.eclipse.jgit.api.errors.JGitInternalException; |
|
|
@@ -197,17 +199,34 @@ public class DescribeCommand extends GitCommand<String> { |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
private boolean tagMatches(Ref tag) { |
|
|
|
if (tag == null) { |
|
|
|
return false; |
|
|
|
private Optional<Ref> getBestMatch(List<Ref> tags) { |
|
|
|
if (tags == null || tags.size() == 0) { |
|
|
|
return Optional.empty(); |
|
|
|
} else if (matchers.size() == 0) { |
|
|
|
return true; |
|
|
|
// No matchers, simply return the first tag entry |
|
|
|
return Optional.of(tags.get(0)); |
|
|
|
} else { |
|
|
|
return matchers.stream() |
|
|
|
.anyMatch(m -> m.matches(tag.getName(), false)); |
|
|
|
// Find the first tag that matches one of the matchers; precedence according to matcher definition order |
|
|
|
for (IMatcher matcher : matchers) { |
|
|
|
Optional<Ref> match = tags.stream() |
|
|
|
.filter(tag -> matcher.matches(tag.getName(), false)) |
|
|
|
.findFirst(); |
|
|
|
if (match.isPresent()) { |
|
|
|
return match; |
|
|
|
} |
|
|
|
} |
|
|
|
return Optional.empty(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private ObjectId getObjectIdFromRef(Ref r) { |
|
|
|
ObjectId key = repo.peel(r).getPeeledObjectId(); |
|
|
|
if (key == null) { |
|
|
|
key = r.getObjectId(); |
|
|
|
} |
|
|
|
return key; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Describes the specified commit. Target defaults to HEAD if no commit was |
|
|
|
* set explicitly. |
|
|
@@ -228,14 +247,9 @@ public class DescribeCommand extends GitCommand<String> { |
|
|
|
if (target == null) |
|
|
|
setTarget(Constants.HEAD); |
|
|
|
|
|
|
|
Map<ObjectId, Ref> tags = new HashMap<>(); |
|
|
|
|
|
|
|
for (Ref r : repo.getRefDatabase().getRefs(R_TAGS).values()) { |
|
|
|
ObjectId key = repo.peel(r).getPeeledObjectId(); |
|
|
|
if (key == null) |
|
|
|
key = r.getObjectId(); |
|
|
|
tags.put(key, r); |
|
|
|
} |
|
|
|
Collection<Ref> tagList = repo.getRefDatabase().getRefs(R_TAGS).values(); |
|
|
|
Map<ObjectId, List<Ref>> tags = tagList.stream() |
|
|
|
.collect(Collectors.groupingBy(this::getObjectIdFromRef)); |
|
|
|
|
|
|
|
// combined flags of all the candidate instances |
|
|
|
final RevFlagSet allFlags = new RevFlagSet(); |
|
|
@@ -281,11 +295,11 @@ public class DescribeCommand extends GitCommand<String> { |
|
|
|
} |
|
|
|
List<Candidate> candidates = new ArrayList<>(); // all the candidates we find |
|
|
|
|
|
|
|
// is the target already pointing to a tag? if so, we are done! |
|
|
|
Ref tagOnTarget = tags.get(target); |
|
|
|
if (tagMatches(tagOnTarget)) { |
|
|
|
return longDesc ? longDescription(tagOnTarget, 0, target) : tagOnTarget |
|
|
|
.getName().substring(R_TAGS.length()); |
|
|
|
// is the target already pointing to a suitable tag? if so, we are done! |
|
|
|
Optional<Ref> bestMatch = getBestMatch(tags.get(target)); |
|
|
|
if (bestMatch.isPresent()) { |
|
|
|
return longDesc ? longDescription(bestMatch.get(), 0, target) : |
|
|
|
bestMatch.get().getName().substring(R_TAGS.length()); |
|
|
|
} |
|
|
|
|
|
|
|
w.markStart(target); |
|
|
@@ -297,9 +311,9 @@ public class DescribeCommand extends GitCommand<String> { |
|
|
|
// if a tag already dominates this commit, |
|
|
|
// 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 (tagMatches(t)) { |
|
|
|
Candidate cd = new Candidate(c, t); |
|
|
|
bestMatch = getBestMatch(tags.get(c)); |
|
|
|
if (bestMatch.isPresent()) { |
|
|
|
Candidate cd = new Candidate(c, bestMatch.get()); |
|
|
|
candidates.add(cd); |
|
|
|
cd.depth = seen; |
|
|
|
} |