{"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/290d5ab72cc1102813fbc0406fb186ceadabc340/src/coreclr/scripts/jitrollingbuild.py#L188-L224","documentation":"Thrown by process_git_hash_arg() when 'git merge-base current_hash main_hash' returns a non-zero exit code. The merge-base identifies the common ancestor between the current commit and the newest remote main commit, which serves as the starting point for searching JIT changes in the rolling build store.","triggerScenarios":"Called after successfully determining current_hash and main_hash. The script runs 'git merge-base <current_hash> <main_hash>'. If git returns non-zero, the RuntimeError is raised at line 206.","commonSituations":"The current_hash and main_hash have no common ancestor (e.g., the repository was rebased onto an unrelated history, or the commits reference different object stores in a shallow/partial clone). A shallow clone truncated the common ancestor commit. The main_hash was parsed incorrectly from the branch listing output.","solutions":["Run 'git merge-base HEAD origin/main' manually to see the exact error.","If using a shallow clone, deepen it with 'git fetch --unshallow' to ensure the common ancestor is present.","Pass -git_hash explicitly to bypass auto-detection and avoid the merge-base computation.","Verify that main_hash (from the previous git branch command) was correctly identified as a valid commit."],"exampleFix":"# before: shallow clone missing merge-base ancestor\npython jitrollingbuild.py download\n\n# after: deepen the clone\ngit fetch --unshallow\npython jitrollingbuild.py download","handlingStrategy":"validation","validationCode":"# Verify merge-base is computable before running auto-detection\nimport subprocess\nresult = subprocess.run(['git', 'merge-base', 'HEAD', 'origin/main'], capture_output=True, cwd=repo_path)\nif result.returncode != 0:\n    print('Cannot compute merge-base. Try deepening a shallow clone or pass -git_hash.')","typeGuard":"def can_compute_merge_base(repo_path: str, ref_a: str, ref_b: str) -> bool:\n    result = subprocess.run(['git', 'merge-base', ref_a, ref_b], capture_output=True, cwd=repo_path)\n    return result.returncode == 0","tryCatchPattern":"try:\n    process_git_hash_arg(coreclr_args)\nexcept RuntimeError as e:\n    if 'baseline git hash' in str(e):\n        logging.error('Merge-base failed. If using shallow clone, run: git fetch --unshallow')\n        sys.exit(1)\n    raise","preventionTips":["Avoid shallow clones for JIT rolling build workflows; use full clones or deepen as needed.","Run 'git fetch --unshallow' if you encounter merge-base failures on a shallow clone.","Pass -git_hash to bypass merge-base computation entirely."],"tags":["git","jitrollingbuild","infrastructure","shallow-clone","merge-base"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}