Skip to content

Commit

Permalink
fix: handle tags within git worktrees directories
Browse files Browse the repository at this point in the history
  • Loading branch information
qoomon committed Feb 17, 2023
1 parent d45c1f0 commit 00b0439
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 44 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

# Changelog

## 9.6.4

##### Fixes
- handle tags within git worktrees directories


## 9.6.3

##### Fixes
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ create or update `${rootProjectDir}/.mvn/extensions.xml` file
<extension>
<groupId>me.qoomon</groupId>
<artifactId>maven-git-versioning-extension</artifactId>
<version>9.6.3</version>
<version>9.6.4</version>
</extension>

</extensions>
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<prerequisites>
<maven>3.6.3</maven>
<maven>3.6.4</maven>
</prerequisites>

<groupId>me.qoomon</groupId>
<artifactId>maven-git-versioning-extension</artifactId>
<version>9.6.3</version>
<version>9.6.4</version>
<packaging>maven-plugin</packaging>

<name>Maven Git Versioning Extension</name>
Expand Down
33 changes: 4 additions & 29 deletions src/main/java/me/qoomon/gitversioning/commons/GitSituation.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package me.qoomon.gitversioning.commons;

import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -19,16 +17,14 @@
import static java.util.Collections.emptyList;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;
import static me.qoomon.gitversioning.commons.GitUtil.NO_COMMIT;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static me.qoomon.gitversioning.commons.GitUtil.*;

public class GitSituation {

private final Repository repository;
private final File rootDirectory;

private final ObjectId head;
private final String rev;
private final Supplier<ZonedDateTime> timestamp = Lazy.by(this::timestamp);
private Supplier<String> branch = Lazy.by(this::branch);

Expand All @@ -44,37 +40,16 @@ public class GitSituation {

public GitSituation(Repository repository) throws IOException {
this.repository = repository;
this.rootDirectory = getWorkTree(repository);
this.head = repository.resolve(HEAD);
this.rev = head != null ? head.getName() : NO_COMMIT;
}

/**
* fixed version repository.getWorkTree()
* handle worktrees as well
*
* @param repository
* @return .git directory
*/
private File getWorkTree(Repository repository) throws IOException {
try {
return repository.getWorkTree();
} catch (NoWorkTreeException e) {
File gitDirFile = new File(repository.getDirectory(), "gitdir");
if (gitDirFile.exists()) {
String gitDirPath = Files.readAllLines(gitDirFile.toPath()).get(0);
return new File(gitDirPath).getParentFile();
}
throw e;
}
this.rootDirectory = worktreesFix_getWorkTree(repository);
this.head = worktreesFix_resolveHead(repository);
}

public File getRootDirectory() {
return rootDirectory;
}

public String getRev() {
return rev;
return head != null ? head.getName() : NO_COMMIT;
}

public ZonedDateTime getTimestamp() {
Expand Down
93 changes: 81 additions & 12 deletions src/main/java/me/qoomon/gitversioning/commons/GitUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.lib.*;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
Expand All @@ -24,6 +26,7 @@
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
import static org.eclipse.jgit.lib.Repository.shortenRefName;

Expand All @@ -48,14 +51,15 @@ public static List<String> tagsPointAt(ObjectId revObjectId, Repository reposito
}

public static GitDescription describe(ObjectId revObjectId, Pattern tagPattern, Repository repository, boolean firstParent) throws IOException {
Repository commonRepository = worktreesFix_getCommonRepository(repository);
if (revObjectId == null) {
return new GitDescription(NO_COMMIT, "root", 0);
}

Map<ObjectId, List<String>> objectIdListMap = reverseTagRefMap(repository);

// Walk back commit ancestors looking for tagged one
try (RevWalk walk = new RevWalk(repository)) {
try (RevWalk walk = new RevWalk(commonRepository)) {
walk.setRetainBody(false);
walk.setFirstParent(firstParent);
walk.markStart(walk.parseCommit(revObjectId));
Expand Down Expand Up @@ -86,17 +90,17 @@ public static boolean isShallowRepository(Repository repository) {
}

public static List<Ref> tags(Repository repository) throws IOException {
return repository.getRefDatabase().getRefsByPrefix(R_TAGS).stream()
// .sorted(new TagComparator(repository)) // TODO may can be removed
.collect(toList());
Repository commonRepository = worktreesFix_getCommonRepository(repository);
return commonRepository.getRefDatabase().getRefsByPrefix(R_TAGS);
}

public static Map<ObjectId, List<String>> reverseTagRefMap(Repository repository) throws IOException {
TagComparator tagComparator = new TagComparator(repository);
return tags(repository).stream()
Repository commonRepository = worktreesFix_getCommonRepository(repository);
TagComparator tagComparator = new TagComparator(commonRepository);
return tags(commonRepository).stream()
.collect(groupingBy(r -> {
try {
Ref peel = repository.getRefDatabase().peel(r);
Ref peel = commonRepository.getRefDatabase().peel(r);
return peel.getPeeledObjectId() != null
? peel.getPeeledObjectId()
: peel.getObjectId();
Expand All @@ -106,15 +110,80 @@ public static Map<ObjectId, List<String>> reverseTagRefMap(Repository repository
}))
.entrySet().stream()
.collect(Collectors.toMap(
e -> e.getKey(),
Entry::getKey,
e -> e.getValue().stream()
.sorted(tagComparator)
.map(v -> shortenRefName(v.getName())).collect(toList())
));
}

public static ZonedDateTime revTimestamp(Repository repository, ObjectId rev) throws IOException {
Instant commitTime = Instant.ofEpochSecond(repository.parseCommit(rev).getCommitTime());
Repository commonRepository = worktreesFix_getCommonRepository(repository);
Instant commitTime = Instant.ofEpochSecond(commonRepository.parseCommit(rev).getCommitTime());
return ZonedDateTime.ofInstant(commitTime, UTC);
}

/**
* @see Repository#getWorkTree()
*/
public static File worktreesFix_getWorkTree(Repository repository) throws IOException {
try {
return repository.getWorkTree();
} catch (NoWorkTreeException e) {
File gitDirFile = new File(repository.getDirectory(), "gitdir");
if (gitDirFile.exists()) {
String gitDirPath = Files.readAllLines(gitDirFile.toPath()).get(0);
return new File(gitDirPath).getParentFile();
}
throw e;
}
}

/**
* @return common repository
*/
public static Repository worktreesFix_getCommonRepository(Repository repository) throws IOException {
try {
repository.getWorkTree();
return repository;
} catch (NoWorkTreeException e) {
File commonDirFile = new File(repository.getDirectory(), "commondir");
if (!commonDirFile.exists()) {
throw e;
}

String commonDirPath = Files.readAllLines(commonDirFile.toPath()).get(0);
File commonGitDir = new File(repository.getDirectory(), commonDirPath);
return new FileRepositoryBuilder().setGitDir(commonGitDir).build();
}
}

/**
* @see Repository#resolve(String)
* @see Constants#HEAD
*/
public static ObjectId worktreesFix_resolveHead(Repository repository) throws IOException {
try {
repository.getWorkTree();
return repository.resolve(HEAD);
} catch (NoWorkTreeException e) {
File headFile = new File(repository.getDirectory(), "HEAD");
if (!headFile.exists()) {
throw e;
}

String head = Files.readAllLines(headFile.toPath()).get(0);
if (head.startsWith("ref:")) {
String refPath = head.replaceFirst("^ref: *", "");

File commonDirFile = new File(repository.getDirectory(), "commondir");
String commonDirPath = Files.readAllLines(commonDirFile.toPath()).get(0);
File commonGitDir = new File(repository.getDirectory(), commonDirPath);

File refFile = new File(commonGitDir, refPath);
head = Files.readAllLines(refFile.toPath()).get(0);
}
return repository.resolve(head);
}
}
}

0 comments on commit 00b0439

Please sign in to comment.