Repository navigation
fix(tools): name a missing head instead of reporting no common ancestor in check_main_sync - #10747
Conversation
…or in check_main_sync report() turned every nonzero exit of git merge-base into "<head> and <base> have no common ancestor", so a mistyped or unfetched --head, a tree or a blob was reported as unrelated history and git's own error was dropped. Now only exit status 1 keeps that message, and any other failure raises "git merge-base failed: <stderr>" like the merge-tree call in conflicts(). git merge-base returns 1 when the histories share no commit and dies with 128 when a revision does not resolve to a commit. The tool still exits 2 in both cases, and test_unrelated_histories_are_an_error now also checks that an invalid head reports git's own merge-base error and not a missing common ancestor.
MarcZX10
left a comment
There was a problem hiding this comment.
Reviewed exact head dfd99b7cb5fcfcf0b1e3275fa888e39a9450acb3. The change distinguishes merge-base exit 1 (unrelated histories) from other failures, and the regression checks a missing revision against Git's actual stderr. I ran python3 tools/tests/test_check_main_sync.py -v (13/13 passed), python3 tools/check_conventions.py --base upstream/main --head upstream/pr-10747, and git diff --check (all passed). Hosted eligibility/conventions/intake/labels and Ubuntu/Windows/macOS relinker plus ASan checks are green; product jobs are skipped by path policy. I found no blocker.
THEMANnt
left a comment
There was a problem hiding this comment.
Reviewed dfd99b7cb5fc against c8d34aa8f4d8. No actionable findings in this focused review.
Source review
report() now distinguishes unrelated histories (git merge-base exit 1) from other Git failures, including a missing head. Those failures retain Git’s diagnostic under git merge-base failed:, while both error paths preserve CLI exit 2. Successful reporting remains unchanged. The test preserves the orphan-history assertions and adds a real CLI invocation for the missing head, comparing its diagnostic with Git’s output from the same temporary repository.
Validation
- Controller-recorded Windows/Python 3.11.9 runs of
tools/tests/test_check_main_sync.py: baseline, pristine PR, and candidate each passed 13 tests with zero skips. - Candidate tests against baseline code failed at the intended missing-head assertion: old code incorrectly reported “no common ancestor.” There were no setup errors.
- The recorded local whitespace and repository-conventions checks returned 0.
- GitHub-reported CI succeeded for the four named relinker matrix jobs,
relinker-asan,eligibility,conventions,intake, andlabels.linux,windows,write-watch, andregister-contextwere skipped; those skips do not establish product-test success.
Scope
Local validation covers the Python tool. The author’s broader build and timing claims were not independently reproduced; full application behavior was not tested.
What
report()intools/check_main_sync.pyraised<head> and <base> have no common ancestorfor every nonzero exit ofgit merge-base, but git returns 1 only when the histories share no commit and dies with 128 when a revision does not resolve to a commit. So--head typoprintederror: typo and main have no common ancestorwhilegit merge-base main typosaysfatal: Not a valid object name typo, and a tree or a blob as--headgot the same message; nothing checks--headbeforereport(), sinceresolve_basechecks only the base.no common ancestormessage; any other nonzero exit raisesgit merge-base failed: <stderr>, the formatconflicts()already uses forgit merge-tree. The tool still exits 2 throughparser.errorin both cases.test_unrelated_histories_are_an_errorkeeps its orphan-branch check (--head islandstill givesno common ancestor) and now also runs the tool with--head missingand asserts exit 2,git merge-base failed:followed by the stderr ofgit merge-base main missingfrom the same repository, and nono common ancestor. It compares with git's own output instead of fixed wording, which depends on the git version and locale. The assertions are folded into that test, so the case shares its setUp and adds no test method.pr_overlap.pyreports no overlap with open pull requests. fix(tools): report squash-merged PRs in main sync checks #10380 edits both files too;git merge-treeof this branch with its head is clean, and the merged test file passes (16 tests).Tested
Windows 11, Python 3.13.9 (Anaconda), git 2.55.0, GCC 15.2.0 (WinLibs UCRT), relinker-only Release build (
-DANYPS5_RELINKER_ONLY=ON -DBUILD_TESTING=ON); synthetic fixtures only, no title or homebrew, relinked outputs not run.main(2dc8560) the amendedtest_unrelated_histories_are_an_errorfails withAssertionError: 'git merge-base failed: fatal: Not a valid object name missing' not found in '... check_main_sync.py: error: missing and main have no common ancestor\n'; with the change it passes.tools/tests/test_check_main_sync.pyrun directly: 13 tests OK in 15.2 s;ctest --test-dir build-relinker -R '^check_main_sync$': passed in 15.5 s. Merged with the head of fix(tools): report squash-merged PRs in main sync checks #10380 (c9ace48), the file runs 16 tests OK in 20.4 s. On the Windows CI runners the file as on main already takes 31.0-32.6 s (four of five runs on 2026-10-24, --parallel 4) and gets the slow-test warning; the measured cost of the added assertions is in the next bullet.check_main_synctakes 31.68 s on the Windows runner with the files as onmain(#42: check_main_sync ... Passed 31.68 sec, CI run of fix(relinker): validate every entry of the Linux run path #10607 on d2a2889). Locally, the folded assertions add about 0.17 s totest_unrelated_histories_are_an_error(0.74 s against 0.58 s, mean of three runs each) and nothing distinguishable from noise to the file (15.22 s on this commit against 15.46 s on 2dc8560, mean of three interleaved runs each, 13 tests in both). Splitting thecheck_main_syncctest entry is a separate topic and stays out of this PR.--base main:--head typogivesgit merge-base failed: fatal: Not a valid object name typo,--head 'HEAD^{tree}'givesgit merge-base failed: error: object ... is a tree, not a commitfollowed byfatal: Not a valid commit name HEAD^{tree}, both exit 2; the orphan branch still givesno common ancestor, exit 2;--head HEADgivesmerge: clean, exit 0.ctest --test-dir build-relinker -j 4: 244 tests, 241 passed,long_pathsskipped;select_tests(Windows symlink fixture,FileExistsErrorintools/tests/test_select_tests.py) andpatch_advisor_unit(a temporary directory path with a space or an 8.3 short name; fix open in test(tools): compare quoted and resolved paths in the patch advisor test #10667) fail on this machine onmainas well.python tools/check_conventions.py --base upstream/mainwith this title and description passed.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)