diff --git a/Misc/NEWS.d/next/Tools-Demos/2026-08-19-17-36-21.gh-issue-156064.xbNrA0.rst b/Misc/NEWS.d/next/Tools-Demos/2026-08-19-17-36-21.gh-issue-156064.xbNrA0.rst new file mode 100644 index 000000000000000..7986f7bd0bc1462 --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/2026-08-19-17-36-21.gh-issue-156064.xbNrA0.rst @@ -0,0 +1,3 @@ +Fix ``make patchcheck`` not finding the upstream remote in a partial clone, +where ``git remote -v`` appends the object filter (for example +``[blob:none]``) after ``(fetch)``. diff --git a/Tools/patchcheck/patchcheck.py b/Tools/patchcheck/patchcheck.py index 1a5797f74223bda..99fb2805ed68dc1 100755 --- a/Tools/patchcheck/patchcheck.py +++ b/Tools/patchcheck/patchcheck.py @@ -68,10 +68,16 @@ def get_git_upstream_remote(): cwd=SRCDIR, encoding="UTF-8" ) + # Keep the "(fetch)" lines only. A partial clone lists its filter after + # the URL type, e.g. "upstream\thttps://github.com/python/cpython (fetch) + # [blob:none]", so "(fetch)" is not necessarily at the end of the line. + fetch_remotes = [ + remote for remote in output.split('\n') if "(fetch)" in remote + ] # Filter to desired remotes, accounting for potential uppercasing filtered_remotes = { - remote.split("\t")[0].lower() for remote in output.split('\n') - if "python/cpython" in remote.lower() and remote.endswith("(fetch)") + remote.split("\t")[0].lower() for remote in fetch_remotes + if "python/cpython" in remote.lower() } if len(filtered_remotes) == 1: [remote] = filtered_remotes @@ -79,9 +85,7 @@ def get_git_upstream_remote(): for remote_name in ["upstream", "origin", "python"]: if remote_name in filtered_remotes: return remote_name - remotes_found = "\n".join( - {remote for remote in output.split('\n') if remote.endswith("(fetch)")} - ) + remotes_found = "\n".join(fetch_remotes) raise ValueError( f"Patchcheck was unable to find an unambiguous upstream remote, " f"with URL matching 'https://github.com/python/cpython'. "