elastic/elasticsearch · error · GradleException
Can't find revision for refName ${refName}
Error message
Can't find revision for refName ${refName} What it means
GitInfo.gitInfo reads the .git metadata directly instead of forking git. When HEAD points at a ref (e.g. refs/heads/main) but neither a loose ref file at that path nor a matching entry in packed-refs exists, the revision cannot be resolved and this GradleException is thrown. The error log just above lists whatever refs were found (or reports no refs dir) to aid diagnosis.
Source
Thrown at build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/info/GitInfo.java:125
} else if (Files.exists(gitDir.resolve("packed-refs"))) {
// Check packed references for commit ID
Pattern p = Pattern.compile("^([a-f0-9]{40}) " + refName + "$");
try (Stream<String> lines = Files.lines(gitDir.resolve("packed-refs"))) {
revision = lines.map(p::matcher)
.filter(Matcher::matches)
.map(m -> m.group(1))
.findFirst()
.orElseThrow(() -> new IOException("Packed reference not found for refName " + refName));
}
} else {
File refsDir = gitDir.resolve("refs").toFile();
if (refsDir.exists()) {
String foundRefs = Arrays.stream(refsDir.listFiles()).map(f -> f.getName()).collect(Collectors.joining("\n"));
Logging.getLogger(GitInfo.class).error("Found git refs\n" + foundRefs);
} else {
Logging.getLogger(GitInfo.class).error("No git refs dir found");
}
throw new GradleException("Can't find revision for refName " + refName);
}
} else {
// we are in detached HEAD state
revision = ref;
}
return new GitInfo(revision, findOriginUrl(gitDir.resolve("config")));
} catch (final IOException e) {
// for now, do not be lenient until we have better understanding of real-world scenarios where this happens
throw new GradleException("unable to read the git revision", e);
}
}
private static String findOriginUrl(final Path configFile) throws IOException {
Map<String, String> props = new HashMap<>();
try (Stream<String> stream = Files.lines(configFile, StandardCharsets.UTF_8)) {
Iterator<String> lines = stream.iterator();View on GitHub (pinned to db6a809a66)
Solutions
- Re-clone the repository to get a clean .git directory.
- Run `git fsck --full` and `git pack-refs --all` to repair and consolidate refs, then retry.
- Check the logged `Found git refs` / `No git refs dir found` message to see what the parser actually saw.
- If reproducible only in a specific worktree, recreate the worktree with `git worktree add`.
Example fix
// before: HEAD points at refs/heads/main but no loose/packed ref exists // repair the refstore git fsck --full && git pack-refs --all
Defensive patterns
Strategy: fallback
Validate before calling
// Before relying on GitInfo.gitInfo, sanity-check the refstore
Path dotGit = rootDir.toPath().resolve(".git");
Path head = Files.isDirectory(dotGit) ? dotGit.resolve("HEAD") : dotGit;
String ref = Files.readString(head).trim();
if (ref.startsWith("ref:")) {
String refName = ref.substring("ref:".length()).trim();
Path loose = dotGit.resolve(refName);
Path packed = dotGit.resolve("packed-refs");
if (!Files.exists(loose) && (!Files.exists(packed) || Files.readString(packed).lines().noneMatch(l -> l.endsWith(" " + refName)))) {
getLogger().warn("Git ref {} cannot be resolved locally; run git fsck", refName);
}
} Try / catch
// GitInfo is called by build internals; if you invoke it directly, degrade gracefully
try {
GitInfo info = GitInfo.gitInfo(rootDir);
} catch (GradleException e) {
if (e.getMessage().contains("Can't find revision")) {
getLogger().warn("Git ref missing; using 'unknown' revision");
info = new GitInfo("unknown", "unknown"); // constructor is private; use a fallback property instead
} else { throw e; }
} Prevention
- Build only from healthy, freshly-cloned repositories.
- Run `git fsck --full` in CI before the build to catch refstore corruption.
- Avoid manually editing .git internals.
When it happens
Trigger: HEAD contains `ref: refs/heads/<branch>` but the loose ref file is absent AND packed-refs is either missing or lacks the matching line. This happens in a broken worktree, a corrupted repo, or an exotic git layout the manual parser does not handle.
Common situations: A corrupted .git after an interrupted operation; a manually constructed git directory without packed-refs; a CI image built from a tarball that dropped loose refs; switching branches while the refstore is being rewritten; very old git clients producing layouts the parser does not expect.
Related errors
- unable to read the git revision
- Found the following merge commits which prevent determining
- Changelog directory contains changes that will be wiped out
- Failed to fetch branch {normalizedBranch} from {sourceRepo}
- Cannot use a commit SHA ({branchRef}) as --branch when fetch
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/4a88d4a49f34bafc.
Report an issue: GitHub.