dotnet/runtime · error · RuntimeError

Couldn't determine current git hash

Error message

Couldn't determine current git hash

What it means

Raised by process_git_hash_arg() in jitrollingbuild.py when 'git rev-parse HEAD' fails (returns non-zero exit code). This command retrieves the current commit hash of the repository. The failure means git cannot determine the current HEAD, which is the starting point for finding a baseline JIT build for asm diffs.

Solutions

  1. Verify the script is being run from within a valid git clone of the dotnet/runtime repository.
  2. Check that 'git rev-parse HEAD' works manually from the same directory.
  3. Ensure git is installed and on PATH (run 'which git').
  4. If using -git_hash argument instead, this code path is skipped entirely — pass -git_hash to bypass the auto-detection.
  5. Verify coreclr_args.runtime_repo_location points to the correct repo root.

Example fix

# before
command = ["git", "rev-parse", "HEAD"]
proc = subprocess.Popen(command, stdout=subprocess.PIPE)
stdout_git_rev_parse, _ = proc.communicate()
return_code = proc.returncode
if return_code == 0:
    current_hash = stdout_git_rev_parse.decode('utf-8').strip()
else:
    raise RuntimeError("Couldn't determine current git hash")

# after - include git stderr in error for diagnosis
command = ["git", "rev-parse", "HEAD"]
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout_git_rev_parse, stderr = proc.communicate()
return_code = proc.returncode
if return_code == 0:
    current_hash = stdout_git_rev_parse.decode('utf-8').strip()
else:
    raise RuntimeError(
        "Couldn't determine current git hash: {}".format(
            stderr.decode('utf-8').strip()))
Defensive patterns

Strategy: validation

Validate before calling

import subprocess, os

def can_determine_git_hash(repo_path: str) -> bool:
    """Check if git rev-parse HEAD works in the given repo."""
    if not os.path.isdir(os.path.join(repo_path, '.git')):
        return False
    result = subprocess.run(
        ['git', 'rev-parse', 'HEAD'],
        cwd=repo_path, capture_output=True)
    return result.returncode == 0 and bool(result.stdout.strip())

# Usage before calling process_git_hash_arg:
if not can_determine_git_hash(coreclr_args.runtime_repo_location):
    print("ERROR: Cannot determine git hash. Pass -git_hash explicitly.")
    sys.exit(1)

Type guard

null

Try / catch

try:
    process_git_hash_arg(coreclr_args)
except RuntimeError as e:
    if "current git hash" in str(e):
        logging.error(f"Git error: {e}. Ensure you're in a valid git repo or pass -git_hash.")
    raise

Prevention

When it happens

Trigger: Triggered when subprocess.Popen(['git', 'rev-parse', 'HEAD']) returns a non-zero returncode. The command is run from coreclr_args.runtime_repo_location (the root of the runtime repo). This fails if the directory is not a git repository, if HEAD is detached in a broken state, if git is not installed or not on PATH, or if the .git directory is corrupt.

Common situations: The script is run from a directory that is not a git repo (e.g., a downloaded tarball instead of a clone). The git binary is not available in the environment. The repository is in a corrupted state after an interrupted operation. The runtime_repo_location was computed incorrectly and points to a non-repo directory.

Related errors


AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10). Data as JSON: /api/errors/ec48241d69eb4c3f. Report an issue: GitHub.

Appendix: source

Thrown at src/coreclr/scripts/jitrollingbuild.py:185

    """

    if coreclr_args.git_hash is not None:
        return

    # Do all the remaining commands, including a number of 'git' commands including relative paths,
    # from the root of the runtime repo.

    with ChangeDir(coreclr_args.runtime_repo_location):
        command = [ "git", "rev-parse", "HEAD" ]
        logging.debug("Invoking: {}".format(" ".join(command)))
        proc = subprocess.Popen(command, stdout=subprocess.PIPE)
        stdout_git_rev_parse, _ = proc.communicate()
        return_code = proc.returncode
        if return_code == 0:
            current_hash = stdout_git_rev_parse.decode('utf-8').strip()
            logging.info("Current hash: {}".format(current_hash))
        else:
            raise RuntimeError("Couldn't determine current git hash")

        # We've got the current hash; figure out the baseline hash.
        # First find the newest hash for any branch matching */main.
        command = [ "git", "branch", "-r", "--sort=-committerdate", "-v", "--list", "*/main" ]
        logging.debug("Invoking: %s", " ".join(command))
        proc = subprocess.Popen(command, stdout=subprocess.PIPE)
        stdout_git_main_branch, _ = proc.communicate()
        return_code = proc.returncode
        if return_code != 0:
            raise RuntimeError("Couldn't determine newest 'main' git hash")

        main_hash = stdout_git_main_branch.decode('utf-8').strip().split()[1]

        # Get the merge-base between the newest main and our current rev
        command = [ "git", "merge-base", current_hash, main_hash ]
        logging.debug("Invoking: %s", " ".join(command))
        proc = subprocess.Popen(command, stdout=subprocess.PIPE)
        stdout_git_merge_base, _ = proc.communicate()

View on GitHub (pinned to 60108ba66e)