{"record":{"id":"ddd5b2842ea1fc19","repo":"dotnet/runtime","slug":"couldn-t-create-git-diff","errorCode":null,"errorMessage":"Couldn't create git diff","messagePattern":"Couldn't create git diff","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/coreclr/scripts/superpmi.py","lineNumber":2527,"sourceCode":"                                ran_jit_analyze = True\n\n                        if not ran_jit_analyze:\n                            logging.info(\"jit-analyze not found on PATH. Generate a diff analysis report by building jit-analyze from https://github.com/dotnet/jitutils and running:\")\n                            logging.info(\"    jit-analyze -r --base %s --diff %s\", base_asm_location, diff_asm_location)\n\n                        if self.coreclr_args.git_diff:\n                            asm_diffs_location = os.path.join(asm_root_dir, \"asm_diffs.diff\")\n                            git_diff_command = [ \"git\", \"diff\", \"--output=\" + asm_diffs_location, \"--no-index\", \"--\", base_asm_location, diff_asm_location ]\n                            git_diff_time = time.time() * 1000\n                            git_diff_proc = subprocess.Popen(git_diff_command, stdout=subprocess.PIPE)\n                            git_diff_proc.communicate()\n                            git_diff_elapsed_time = round((time.time() * 1000) - git_diff_time, 1)\n                            git_diff_return_code = git_diff_proc.returncode\n                            if git_diff_return_code == 0 or git_diff_return_code == 1: # 0 means no differences and 1 means differences\n                                logging.info(\"Created git diff file at %s in %s ms\", asm_diffs_location, git_diff_elapsed_time)\n                                logging.info(\"-------\")\n                            else:\n                                raise RuntimeError(\"Couldn't create git diff\")\n\n                    else:\n                        logging.warning(\"No textual differences. Is this an issue with coredistools?\")\n\n                    # If we are not specifying custom metrics then print a summary here, otherwise leave the summarization up to jit-analyze.\n                    if self.coreclr_args.metrics is None:\n                        base_diff_sizes = [(int(r[\"Base ActualCodeBytes\"]), int(r[\"Diff ActualCodeBytes\"])) for r in diffs]\n                        (num_size_improvements, num_size_regressions, num_size_same, byte_improvements, byte_regressions) = calculate_size_improvements_regressions(base_diff_sizes)\n\n                        num_diffs_str = \"{:,d} contexts with diffs\".format(len(diffs))\n                        logging.info(\"{} ({:,d} size improvements, {:,d} size regressions, {:,d} same size)\".format(\n                            num_diffs_str,\n                            num_size_improvements,\n                            num_size_regressions,\n                            num_size_same,\n                            byte_improvements,\n                            byte_regressions))\n","sourceCodeStart":2509,"sourceCodeEnd":2545,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/coreclr/scripts/superpmi.py#L2509-L2545","documentation":"Raised during assembly-diff generation when the subprocess 'git diff --output=<asm_diffs.diff> --no-index -- <base_asm_location> <diff_asm_location>' returns a code that is neither 0 (identical) nor 1 (differences found). git uses exit codes 0/1 for normal diff results, so any other code indicates git itself failed (e.g. missing input path, git not installed, permission error). The diff file that documents textual asm differences cannot be produced.","triggerScenarios":"Triggered in the asm-diff branch when coreclr_args.git_diff is True: subprocess.Popen runs git diff --no-index on two assembly output directories; git_diff_proc.returncode is not in {0,1}. This occurs when one of the asm locations does not exist, when git is not on PATH, when paths contain characters git rejects, or when the --output target directory is unwritable.","commonSituations":"Running 'superpmi.py asmdiff' after a partial run where one side produced no .dasm files; git not installed or not on PATH in a minimal container; a typo or wrong -base/--diff path; running on Windows where git is present but path quoting breaks the --no-index invocation.","solutions":["Run the git diff command printed in the debug log manually to see git's real stderr message.","Verify both base_asm_location and diff_asm_location exist and contain .dasm files before enabling --git_diff.","Ensure git is installed and on PATH (git --version succeeds) in the execution environment.","Confirm the output path asm_diffs_location is in a writable directory."],"exampleFix":"// before\ngit_diff_command = [\"git\", \"diff\", \"--output=\" + asm_diffs_location, \"--no-index\", \"--\", base_asm_location, diff_asm_location]\ngit_diff_proc = subprocess.Popen(git_diff_command, stdout=subprocess.PIPE)\ngit_diff_proc.communicate()\nif git_diff_proc.returncode not in (0, 1):\n    raise RuntimeError(\"Couldn't create git diff\")\n// after\ngit_diff_proc = subprocess.Popen(git_diff_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n_, stderr = git_diff_proc.communicate()\nif git_diff_proc.returncode not in (0, 1):\n    raise RuntimeError(f\"git diff failed (code {git_diff_proc.returncode}): {stderr.decode('utf-8', 'replace').strip()}\")","handlingStrategy":"validation","validationCode":"import os, shutil, subprocess\ndef preflight_git_diff(base_asm_location, diff_asm_location, asm_diffs_location):\n    import shutil as _s\n    if shutil.which('git') is None:\n        raise RuntimeError('git not found on PATH')\n    for p in (base_asm_location, diff_asm_location):\n        if not os.path.isdir(p):\n            raise RuntimeError(f'asm location is not a directory: {p}')\n    out_dir = os.path.dirname(asm_diffs_location)\n    if not os.path.isdir(out_dir) or not os.access(out_dir, os.W_OK):\n        raise RuntimeError(f'output dir missing or not writable: {out_dir}')","typeGuard":null,"tryCatchPattern":"git_diff_proc = subprocess.Popen(git_diff_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n_, stderr = git_diff_proc.communicate()\nif git_diff_proc.returncode not in (0, 1):\n    raise RuntimeError(f\"git diff failed (code {git_diff_proc.returncode}): {stderr.decode('utf-8', 'replace').strip()}\")","preventionTips":["Ensure both asm output directories exist and contain .dasm files before enabling --git_diff.","Confirm git is installed and on PATH in CI containers.","Capture stderr from the git subprocess so failures are diagnosable."],"tags":["git","asmdiff","subprocess","superpmi"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}