Skip to content

Commit a19711e

Browse files
committed
Valid tags give a default offset of 0
Previously, tags that were created for a subproject needed to include a commit that modified a file within the path. This is no longer required and as long as the tag is created for the project's tag prefix, it will be counted as part of the project. For example, for project hash-utils with tag prefix 'hash', we have three commits: 1. An empty commit tagged 'hash-0.3' 2. A commit that modifies a file in the 'hash-utils' directory 3. A commit that does not modify any files in 'hash-utils' Commits 1 and 2 would be counted, but 3 would not. The resulting version number will be 0.3.1. This is currently using an implementation detail regarding how JGit's LogCommand returns its result. See eclipse-jgit/jgit#149
1 parent 16212c4 commit a19711e

File tree

5 files changed

+43
-21
lines changed

5 files changed

+43
-21
lines changed

build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ dependencies {
3939
shadowOnly libs.slf4j
4040
shadowOnly libs.jopt
4141
compileOnly libs.jopt
42+
//runtimeOnly libs.jopt
4243

4344
// Static Analysis
4445
compileOnly libs.nulls

src/main/java/net/minecraftforge/gitver/internal/GitChangelog.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ static String generateChangelogFromTo(Git git, String repositoryUrl, boolean pla
4444

4545
var changeLogName = Util.replace(git.getRepository().getFullBranch(), s -> s.replace("refs/heads/", "")); //Generate a changelog name from the current branch.
4646

47-
var log = GitUtils.getCommitLogFromTo(git, start, end, filter); //Get all commits between the start and the end.
47+
var tagMap = GitUtils.getCommitToTagMap(git, tagPrefix); //Grab a map between commits and tag names.
48+
var log = GitUtils.getCommitLogFromTo(git, tagMap, start, end, tagPrefix, filter); //Get all commits between the start and the end.
4849
var logList = new ArrayList<RevCommit>(); //And generate a list from it.
4950
log.forEach(logList::add);
5051

51-
var tagMap = GitUtils.getCommitToTagMap(git, tagPrefix); //Grab a map between commits and tag names.
5252
var versionMap = GitUtils.buildVersionMap(logList, tagMap); //And generate a version map from this. Mapping each commit to a unique version.
5353
var primaryVersionMap = GitUtils.getPrimaryVersionMap(logList, tagMap); //Then determine which commits belong to which identifiable-version mappings.
5454

src/main/java/net/minecraftforge/gitver/internal/GitUtils.java

+29-14
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88
import org.eclipse.jgit.api.ListBranchCommand;
99
import org.eclipse.jgit.api.errors.GitAPIException;
1010
import org.eclipse.jgit.errors.MissingObjectException;
11+
import org.eclipse.jgit.errors.StopWalkException;
1112
import org.eclipse.jgit.lib.Constants;
1213
import org.eclipse.jgit.lib.ObjectId;
1314
import org.eclipse.jgit.lib.Ref;
1415
import org.eclipse.jgit.revwalk.RevCommit;
1516
import org.eclipse.jgit.revwalk.RevWalk;
17+
import org.eclipse.jgit.revwalk.TreeRevFilter;
18+
import org.eclipse.jgit.revwalk.filter.OrRevFilter;
1619
import org.eclipse.jgit.revwalk.filter.RevFilter;
1720
import org.eclipse.jgit.transport.RemoteConfig;
1821
import org.eclipse.jgit.util.StringUtils;
@@ -62,7 +65,7 @@ static String getRelativePath(File root, File file) {
6265
* Counts commits, for the given Git repository, from the given tag to {@linkplain Constants#HEAD HEAD}. If the
6366
* given tag cannot be found, this method will return {@code -1}.
6467
* <p>
65-
* See {@link #countCommits(Git, ObjectId, Iterable, Iterable)} for more information.
68+
* See {@link #countCommits(Git, Map, ObjectId, String, Iterable, Iterable)} for more information.
6669
*
6770
* @param git The git repository to count commits in
6871
* @param tag The tag name to start counting from
@@ -72,14 +75,14 @@ static String getRelativePath(File root, File file) {
7275
* @throws GitAPIException If an error occurs when running the log command (see
7376
* {@link org.eclipse.jgit.api.LogCommand#call() LogCommand.call()}
7477
* @throws IOException If an I/O error occurs when reading the Git repository
75-
* @see #countCommits(Git, ObjectId, Iterable, Iterable)
78+
* @see #countCommits(Git, Map, ObjectId, String, Iterable, Iterable)
7679
*/
77-
static int countCommits(Git git, String tag, Iterable<String> includePaths, Iterable<String> excludePaths) throws GitAPIException, IOException {
80+
static int countCommits(Git git, String tag, String tagPrefix, Iterable<String> includePaths, Iterable<String> excludePaths) throws GitAPIException, IOException {
7881
var tags = GitUtils.getTagToCommitMap(git);
7982
var commitHash = tags.get(tag);
8083
if (commitHash == null) return -1;
8184

82-
return countCommits(git, ObjectId.fromString(commitHash), includePaths, excludePaths);
85+
return countCommits(git, GitUtils.getCommitToTagMap(git), ObjectId.fromString(commitHash), tagPrefix, includePaths, excludePaths);
8386
}
8487

8588
/**
@@ -102,8 +105,8 @@ static int countCommits(Git git, String tag, Iterable<String> includePaths, Iter
102105
* @see org.eclipse.jgit.api.LogCommand LogCommand
103106
* @see <a href="https://git-scm.com/docs/git-log"><code>git-log</code></a>
104107
*/
105-
static int countCommits(Git git, ObjectId from, Iterable<String> includePaths, Iterable<String> excludePaths) throws GitAPIException, IOException {
106-
return Util.count(getCommitLogFromTo(git, from, getHead(git), includePaths, excludePaths));
108+
static int countCommits(Git git, Map<String, String> commitsToTags, ObjectId from, String tagPrefix, Iterable<String> includePaths, Iterable<String> excludePaths) throws GitAPIException, IOException {
109+
return Util.count(getCommitLogFromTo(git, commitsToTags, from, getHead(git), tagPrefix, includePaths, excludePaths));
107110
}
108111

109112
/**
@@ -157,8 +160,8 @@ static RevCommit getCommitFromId(Git git, ObjectId other) throws IOException {
157160
* {@link org.eclipse.jgit.api.LogCommand#call() LogCommand.call()}
158161
* @throws IOException If an I/O error occurs when reading the Git repository
159162
*/
160-
static Iterable<RevCommit> getCommitLogFromTo(Git git, ObjectId from, ObjectId to, Iterable<String> includePaths) throws GitAPIException, IOException {
161-
return getCommitLogFromTo(git, from, to, includePaths, Collections::emptyIterator);
163+
static Iterable<RevCommit> getCommitLogFromTo(Git git, Map<String, String> tags, ObjectId from, ObjectId to, String tagPrefix, Iterable<String> includePaths) throws GitAPIException, IOException {
164+
return getCommitLogFromTo(git, tags, from, to, tagPrefix, includePaths, Collections::emptyIterator);
162165
}
163166

164167
/**
@@ -174,7 +177,7 @@ static Iterable<RevCommit> getCommitLogFromTo(Git git, ObjectId from, ObjectId t
174177
* {@link org.eclipse.jgit.api.LogCommand#call() LogCommand.call()}
175178
* @throws IOException If an I/O error occurs when reading the Git repository
176179
*/
177-
static Iterable<RevCommit> getCommitLogFromTo(Git git, ObjectId from, ObjectId to, Iterable<String> includePaths, Iterable<String> excludePaths) throws GitAPIException, IOException {
180+
static Iterable<RevCommit> getCommitLogFromTo(Git git, Map<String, String> commitsToTags, ObjectId from, ObjectId to, String tagPrefix, Iterable<String> includePaths, Iterable<String> excludePaths) throws GitAPIException, IOException {
178181
var start = getCommitFromId(git, from);
179182
var end = getCommitFromId(git, to);
180183

@@ -185,13 +188,25 @@ static Iterable<RevCommit> getCommitLogFromTo(Git git, ObjectId from, ObjectId t
185188
log.not(parent);
186189
// We do not exclude the starting commit itself, so the commit is present in the returned iterable
187190

188-
for (var path : includePaths)
189-
log.addPath(path);
191+
boolean hasFilters = Util.forEach(includePaths, log::addPath) || Util.forEach(excludePaths, log::excludePath);
190192

191-
for (var path : excludePaths)
192-
log.excludePath(path);
193+
// TODO [GitVersion][JGit] PR in a solution for creating an OR rev filter
194+
return Util.make((RevWalk) log.call(), walk -> {
195+
if (!hasFilters || StringUtils.isEmptyOrNull(tagPrefix) || commitsToTags == null || commitsToTags.isEmpty()) return;
193196

194-
return log.call();
197+
walk.setRevFilter(OrRevFilter.create(new TreeRevFilter(walk, walk.getTreeFilter()), new RevFilter() {
198+
@Override
199+
public boolean include(RevWalk walker, RevCommit cmit) throws StopWalkException {
200+
return commitsToTags.getOrDefault(ObjectId.toString(cmit), "").startsWith(tagPrefix);
201+
}
202+
203+
@Override
204+
public RevFilter clone() {
205+
throw new UnsupportedOperationException();
206+
}
207+
}));
208+
walk.setTreeFilter(null);
209+
});
195210
}
196211

197212
/**

src/main/java/net/minecraftforge/gitver/internal/GitVersionImpl.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,10 @@ private int getSubprojectCommitCount(Git git, String tag) {
300300

301301
var includePaths = !this.localPath.isEmpty() ? Collections.singleton(this.localPath) : Collections.<String>emptySet();
302302
try {
303-
int count = GitUtils.countCommits(git, tag, includePaths, excludePaths);
304-
if (count >= 0) return count;
305-
306-
throw new GitVersionExceptionInternal("Couldn't find any commits with the following parameters: Tag %s, Include Paths [%s], Exclude Paths [%s]".formatted(tag, String.join(", ", includePaths), String.join(", ", excludePaths)));
303+
int count = GitUtils.countCommits(git, tag, this.tagPrefix, includePaths, excludePaths);
304+
return Math.max(count, 0);
307305
} catch (GitAPIException | IOException e) {
308-
throw new GitVersionExceptionInternal("Failed to count commits", e);
306+
throw new GitVersionExceptionInternal("Failed to count commits with the following parameters: Tag %s, Include Paths [%s], Exclude Paths [%s]".formatted(tag, String.join(", ", includePaths), String.join(", ", excludePaths)));
309307
}
310308
}
311309

src/main/java/net/minecraftforge/gitver/internal/Util.java

+8
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@ static int count(Iterable<?> iterable) {
101101
return null;
102102
}
103103

104+
static <T> boolean forEach(Iterable<T> iterable, Consumer<T> action) {
105+
var it = iterable.iterator();
106+
if (!it.hasNext()) return false;
107+
108+
it.forEachRemaining(action);
109+
return true;
110+
}
111+
104112
static <T> T make(Supplier<T> t) {
105113
return t.get();
106114
}

0 commit comments

Comments
 (0)