{"record":{"id":"39e59661d996f72d","repo":"dotnet/runtime","slug":"couldn-t-determine-baseline-git-hash","errorCode":null,"errorMessage":"Couldn't determine baseline git hash","messagePattern":"Couldn't determine baseline git hash","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/coreclr/scripts/jitrollingbuild.py","lineNumber":206,"sourceCode":"        # First find the newest hash for any branch matching */main.\n        command = [ \"git\", \"branch\", \"-r\", \"--sort=-committerdate\", \"-v\", \"--list\", \"*/main\" ]\n        logging.debug(\"Invoking: %s\", \" \".join(command))\n        proc = subprocess.Popen(command, stdout=subprocess.PIPE)\n        stdout_git_main_branch, _ = proc.communicate()\n        return_code = proc.returncode\n        if return_code != 0:\n            raise RuntimeError(\"Couldn't determine newest 'main' git hash\")\n\n        main_hash = stdout_git_main_branch.decode('utf-8').strip().split()[1]\n\n        # Get the merge-base between the newest main and our current rev\n        command = [ \"git\", \"merge-base\", current_hash, main_hash ]\n        logging.debug(\"Invoking: %s\", \" \".join(command))\n        proc = subprocess.Popen(command, stdout=subprocess.PIPE)\n        stdout_git_merge_base, _ = proc.communicate()\n        return_code = proc.returncode\n        if return_code != 0:\n            raise RuntimeError(\"Couldn't determine baseline git hash\")\n\n        baseline_hash = stdout_git_merge_base.decode('utf-8').strip()\n        logging.info(\"Baseline hash: %s\", baseline_hash)\n\n        # Enumerate the last 20 changes, starting with the baseline, that included JIT and JIT-EE GUID changes.\n        command = [ \"git\", \"log\", \"--pretty=format:%H\", baseline_hash, \"-20\", \"--\", \"src/coreclr/jit/*\", \"src/coreclr/inc/jiteeversionguid.h\" ]\n        logging.debug(\"Invoking: {}\".format(\" \".join(command)))\n        proc = subprocess.Popen(command, stdout=subprocess.PIPE)\n        stdout_change_list, _ = proc.communicate()\n        return_code = proc.returncode\n        change_list_hashes = []\n        if return_code == 0:\n            change_list_hashes = stdout_change_list.decode('utf-8').strip().splitlines()\n        else:\n            raise RuntimeError(\"Couldn't determine list of JIT changes starting with baseline hash\")\n\n        if len(change_list_hashes) == 0:\n            raise RuntimeError(\"No JIT changes found starting with baseline hash\")","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/coreclr/scripts/jitrollingbuild.py#L188-L224","documentation":"Raised by process_git_hash_arg() in jitrollingbuild.py when 'git merge-base <current_hash> <main_hash>' fails. The merge-base command finds the common ancestor between the current commit and the newest main branch commit. This common ancestor is the 'baseline' from which JIT changes are enumerated to find a matching rolling build.","triggerScenarios":"Triggered when git merge-base returns non-zero. This happens if either hash argument is invalid or doesn't exist in the repository, if the two commits have no common ancestor (unrelated histories), or if the repository is in a corrupted state where the object database is inconsistent.","commonSituations":"The current_hash or main_hash was computed incorrectly (e.g., empty string from a failed parse). The repository has divergent histories (e.g., a fork that doesn't share history with upstream). Git objects are missing due to a partial clone or GC operation. A shallow clone doesn't have enough depth to find the merge-base.","solutions":["Verify both current_hash and main_hash are valid commit hashes by running 'git cat-file -t <hash>'.","If using a shallow clone, run 'git fetch --unshallow' to get full history.","Check 'git merge-base <current> <main>' manually to see the error output.","Pass -git_hash explicitly to skip auto-detection entirely.","Ensure the repository is a proper clone with shared history to the remote main branch."],"exampleFix":"# before\ncommand = [\"git\", \"merge-base\", current_hash, main_hash]\nproc = subprocess.Popen(command, stdout=subprocess.PIPE)\nstdout_git_merge_base, _ = proc.communicate()\nreturn_code = proc.returncode\nif return_code != 0:\n    raise RuntimeError(\"Couldn't determine baseline git hash\")\n\n# after - capture and surface stderr for diagnosis\ncommand = [\"git\", \"merge-base\", current_hash, main_hash]\nproc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\nstdout_git_merge_base, stderr = proc.communicate()\nreturn_code = proc.returncode\nif return_code != 0:\n    raise RuntimeError(\n        \"Couldn't determine baseline git hash (current={}, main={}): {}\".format(\n            current_hash, main_hash, stderr.decode('utf-8').strip()))","handlingStrategy":"validation","validationCode":"import subprocess\n\ndef can_compute_merge_base(repo_path: str, hash_a: str, hash_b: str) -> bool:\n    \"\"\"Check if git merge-base succeeds for two hashes.\"\"\"\n    if not hash_a or not hash_b:\n        return False\n    result = subprocess.run(\n        ['git', 'merge-base', hash_a, hash_b],\n        cwd=repo_path, capture_output=True)\n    return result.returncode == 0 and bool(result.stdout.strip())","typeGuard":"null","tryCatchPattern":"try:\n    process_git_hash_arg(coreclr_args)\nexcept RuntimeError as e:\n    if \"baseline git hash\" in str(e):\n        logging.error(f\"{e}. The merge-base between current and main may not exist.\")\n        logging.error(\"Try 'git fetch --unshallow' if using a shallow clone.\")\n    raise","preventionTips":["Avoid shallow clones for JIT rolling build workflows — use full clones.","Ensure current_hash and main_hash are valid before computing merge-base.","Run 'git fetch --unshallow' if the repo was cloned with --depth.","Verify repository integrity with 'git fsck'."],"tags":["git","jit","rolling-build","coreclr","superpmi"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}