fix(update): detect managed-EOL churn from --numstat, not --name-only - #75213
fix(update): detect managed-EOL churn from --numstat, not --name-only#75213Zeraphim wants to merge 3 commits into
Conversation
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the --name-only --ignore-cr-at-eol path; current main still has that exact call at hermes_cli/update_cmd.py:3087.
Problems
hermes_cli/update_cmd.py:3099assumes everygit diff --numstat -zitem isadded\tdeleted\tpath. Git’s documented rename/copy form isadded\tdeleted\tNUL preimage NUL postimage NUL. With rename detection enabled, this comprehension adds only the empty field and omits the postimage. Since--name-onlyreports the postimage path,_eol_only()can mark a real renamed/copied edit as EOL-only and send it tocheckout.
Suggested changes
- Decode the NUL-framed numstat stream, recognizing the rename/copy marker and retaining the postimage path; add a regression case with rename detection enabled.
Automated hermes-sweeper review.
…175-managed-eol-crlf
|
Hello @teknium1, addressed on the latest head 2846789:
|
SummaryThree PRs address Issue #75175 by replacing the ineffective Related pull requests
Duplicates#75213, #75220, and #76431 implement the same root fix of replacing the ineffective ignored-EOL name-only probe with numstat; #75220 is the incomplete duplicate, while #75213 adds defensive NUL-framed rename/copy parsing and a regression test beyond merged #76431. Suggested consolidationClose #75213 as already implemented on main by merged #76431, and retain #75220 as closed as a duplicate of #75213/#76431. The concrete evidence is the merged #76431 diff in Complex graphflowchart LR
classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
classDef best stroke-width:3px,stroke:#b45309
classDef target stroke-width:3px,stroke:#4338ca
I75175(["issue #75175 (open)"])
subgraph Dup75213 ["PRs duplicating each other"]
P75213["PR #75213 (open)"]
P75220["PR #75220 (closed)"]
P76431["PR #76431 (merged)"]
end
P75213 -->|best fix| I75175
class I75175 open
class P75213 open
class P75220 closed
class P76431 merged
class P75213 best
class P75213 target
click I75175 "https://github.com/NousResearch/hermes-agent/issues/75175"
click P75213 "https://github.com/NousResearch/hermes-agent/pull/75213"
click P75220 "https://github.com/NousResearch/hermes-agent/pull/75220"
click P76431 "https://github.com/NousResearch/hermes-agent/pull/76431"
Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed (state tag in the node label). Cross-PR triage: Reviewed 3 pull requests and 1 issue in this complex. Each diff was read against this issue; Assessment working set: 7 kB of PR diffs, 15 kB of issue/PR text, 5 kB of discussion (9 comments), 5 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch. |
What does this PR do?
Fixes a broken line-ending normalization path in the managed-checkout updater.
hermes updateis supposed to take a Git-for-Windows-managed clone (pinnedcore.autocrlf=true, CRLF working tree) off autocrlf and rewrite the churn back to LF before persisting thecore.autocrlf=falsepin. The "churn that is only CRLF" set was computed viagit diff --name-only --ignore-cr-at-eol, but whitespace-ignore flags are inert under--name-only, soeol_onlywas always empty, the cleanup checkout never ran, and the pin was written unconditionally — handing the update a whole-tree autostash of CRLF churn (the regression that made the merged PR #74487 fail its own 5-test cluster)._eol_only()now derives the "files that still differ after ignoring CRLF-at-EOL" set fromgit diff -z --ignore-cr-at-eol --numstat(which honors the flag and omits CRLF-only files) instead of the inert--name-onlylisting. Both call sites — the initial detection and the post-checkout recheck — use the corrected computation, so the whole bug class (detection + verification) is fixed.Related Issue
Fixes #75175
Type of Change
Changes Made
hermes_cli/update_cmd.py: added_real_dirty()reading--numstatto honor--ignore-cr-at-eol;_eol_only()now computesall_dirty - real_dirtywith a working real-diff set. No change to the checkout/recheck/pin flow or fail-safes.How to Test
scripts/run_tests.sh tests/hermes_cli/test_update_eol_churn.py -v→ 5 failures (test_churn_invisible_under_autocrlf_true_is_still_found,test_churn_is_cleared_and_the_pin_is_persisted,test_real_edits_survive_even_when_line_endings_also_flipped,test_pin_is_withheld_when_the_churn_cannot_be_cleared,test_churn_across_more_files_than_fit_in_one_argv).scripts/run_tests.shover the 19-file update family → 114/114 pass.git diff --name-only --ignore-cr-at-eollists CRLF-only files (flag inert);git diff --numstat --ignore-cr-at-eolomits them (flag honored).Checklist
Code
fix(scope):)_normalize_managed_eoldoes not clear CRLF churn — 5-test cluster fails (merged PR #74487 fails its own tests) #75175)scripts/run_tests.sh tests/hermes_cli/test_update_eol_churn.pyand all tests pass (9/9; 114/114 across the update family)test_update_eol_churn.py(failing on main, now passing). No new tests needed; the existing cluster pins the contract.Documentation & Housekeeping
--numstat -zis ancient;--ignore-cr-at-eolrequires git >= 2.35, which the prior code already relied on)