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

  1. Re-clone the repository to get a clean .git directory.
  2. Run `git fsck --full` and `git pack-refs --all` to repair and consolidate refs, then retry.
  3. Check the logged `Found git refs` / `No git refs dir found` message to see what the parser actually saw.
  4. 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

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


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/4a88d4a49f34bafc. Report an issue: GitHub.