{"record":{"id":"9b3c2c75e3149f8b","repo":"dotnet/runtime","slug":"couldn-t-determine-baseline-git-hash-9b3c2c","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/superpmi.py","lineNumber":4892,"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        else:\n            baseline_hash = coreclr_args.base_git_hash\n\n        if coreclr_args.base_git_hash is None:\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: %s\", \" \".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\")","sourceCodeStart":4874,"sourceCodeEnd":4910,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/coreclr/scripts/superpmi.py#L4874-L4910","documentation":"Raised by determine_base_jit when 'git merge-base <current_hash> <main_hash>' returns nonzero. The merge-base identifies the common ancestor commit used as the baseline for JIT diffs. A nonzero code means git could not compute the merge-base, usually because the two hashes have no common history (unrelated refs) or one hash is invalid/unreachable in the current object database.","triggerScenarios":"subprocess.Popen(['git','merge-base', current_hash, main_hash]) returns nonzero. Happens when current_hash and main_hash come from disjoint histories (e.g. a fork unrelated to upstream main), when a hash is not present due to a shallow/partial clone, or when a hash string is malformed.","commonSituations":"Shallow clone missing the merge-base commit object; working on a fork whose history does not share commits with the main branch used; git alternates/multiple worktrees with incomplete object storage; a stale/wrong main_hash from a prior failed step.","solutions":["Deepen the clone to include the common ancestor: 'git fetch --unshallow' or 'git fetch --depth=N' with a larger N.","Verify both hashes exist in the repo: 'git cat-file -t <hash>' for each.","Ensure current and main share history; if using a fork, rebase onto upstream main.","Pass --base_git_hash <sha> explicitly to skip merge-base computation."],"exampleFix":"// before\ncommand = [\"git\", \"merge-base\", current_hash, main_hash]\nproc = subprocess.Popen(command, stdout=subprocess.PIPE)\nstdout_git_merge_base, _ = proc.communicate()\nif proc.returncode != 0:\n    raise RuntimeError(\"Couldn't determine baseline git hash\")\n// after (fix invocation)\ngit -C <repo> fetch --unshallow origin\n# Or pass the baseline directly:\npython superpmi.py asmdiff --base_git_hash <merge-base-sha> ...","handlingStrategy":"validation","validationCode":"import subprocess\ndef validate_merge_base(repo_location, current_hash, main_hash):\n    for h in (current_hash, main_hash):\n        proc = subprocess.run(['git', '-C', repo_location, 'cat-file', '-t', h], capture_output=True)\n        if proc.returncode != 0:\n            raise RuntimeError(f\"hash not present in repo: {h}\")\n    proc = subprocess.run(['git', '-C', repo_location, 'merge-base', current_hash, main_hash], capture_output=True)\n    if proc.returncode != 0:\n        raise RuntimeError(f\"merge-base failed (disjoint histories?): {proc.stderr.decode('utf-8','replace').strip()}\")\n    return proc.stdout.decode('utf-8').strip()","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid shallow clones for baseline detection; use 'git fetch --unshallow' if needed.","Ensure current and main share history (rebase forks onto upstream main).","Pass --base_git_hash explicitly to skip merge-base computation."],"tags":["git","base-jit","merge-base","subprocess","superpmi","asmdiff"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}