Skip to content

fix(update): detect EOL-only churn via numstat, not name-only - #76431

Merged
teknium1 merged 1 commit into
mainfrom
fix/eol-churn-numstat-detection
Aug 1, 2026
Merged

fix(update): detect EOL-only churn via numstat, not name-only#76431
teknium1 merged 1 commit into
mainfrom
fix/eol-churn-numstat-detection

Conversation

@teknium1

@teknium1 teknium1 commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

hermes update on a managed Windows checkout now actually clears line-ending churn before pinning core.autocrlf=false, instead of pinning a still-dirty tree that breaks the next update.

Root cause: _normalize_managed_eol isolated EOL-only churn from real edits by diffing twice — all dirty files minus files still dirty under --ignore-cr-at-eol. But git diff --name-only --ignore-cr-at-eol computes its file list from blob/stat differences before the CR filter is applied, so it still lists CR-only files. On git 2.48.1 the two name-only sets are identical → _eol_only() is always empty → the checkout that would clear the churn is skipped, yet autocrlf=false is pinned anyway, leaving the whole CRLF tree dirty (the exact breakage this function exists to prevent).

Changes

  • hermes_cli/update_cmd.py: compute the real-edit set with git diff --numstat --ignore-cr-at-eol (numstat honors the CR filter — a CR-only file produces no record) instead of --name-only. Pin core.quotepath=false so non-ASCII paths parse.

Validation

git 2.48.1
Before _eol_only() empty → tree left dirty, autocrlf pinned anyway
After eol-only churn cleared, genuine edits preserved, pin applied only after tree reads clean
  • Verified at 1200 files: 1199 EOL-only files normalized to LF, one genuinely-edited file preserved (REAL_EDIT intact), only that file left dirty, autocrlf=false pinned.
  • scripts/run_tests.sh tests/hermes_cli/test_update_eol_churn.py — 9/9 pass (was 1 failing on test_churn_across_more_files_than_fit_in_one_argv).

Pre-existing failure on main — the test failed deterministically on git 2.48.1; surfaced while landing unrelated file-tools PRs (#76394, #76399).

Infographic

EOL churn detection numstat vs name-only

_normalize_managed_eol isolated line-ending churn from real edits by
diffing twice: all dirty files minus files still dirty under
--ignore-cr-at-eol. But 'git diff --name-only --ignore-cr-at-eol'
computes its file list from blob/stat differences BEFORE the CR filter
is applied, so it still lists CR-only files. On git 2.48.1 the two
name-only sets are therefore identical, _eol_only() is always empty, and
a managed Windows checkout gets pinned to core.autocrlf=false with the
whole CRLF tree left dirty — breaking the next 'git checkout' on update
(the exact failure this function exists to prevent).

Compute the real-edit set with 'git diff --numstat --ignore-cr-at-eol'
instead: numstat honors the CR filter (a CR-only file produces no
record), so eol-only files are correctly identified and cleared while
genuine edits are preserved. Pin core.quotepath=false so non-ASCII paths
parse. Verified at 1200 files: 1199 eol-only normalized, one real edit
preserved, autocrlf pinned only after the tree reads clean.

This was a pre-existing failure on main (test_update_eol_churn's
test_churn_across_more_files_than_fit_in_one_argv failed deterministically
on git 2.48.1), surfaced while landing unrelated file-tools PRs.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard platform/windows Native Windows-specific behavior or breakage area/install-update Installer, updater, packaging, wheels, doctor sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades duplicate This issue or pull request already exists labels Aug 1, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #75213. Both replace the ineffective name-only CRLF comparison with numstat; #75213 is the earlier broader implementation and also covers NUL-delimited rename/copy records.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 7e89ed9

ℹ️ Info

Desktop E2E visual evidence · View test artifacts · View job

3 visual diffs.

inline evidence upload failed.

Failed to upload diff-1508682a2ae8-boot-ready-diff.png with gh image (exit code 1): Error uploading /home/runner/work/_temp/e2e-evidence/diff-1508682a2ae8-boot-ready-diff.png: step 0 (get upload token): uploadToken not found on repo page — do you have write access to NousResearch/hermes-agent? (or, if NousResearch enforces SAML SSO, authorize at https://github.com/orgs/NousResearch/sso)

@teknium1
teknium1 merged commit ff6ed7c into main Aug 1, 2026
41 checks passed
@teknium1
teknium1 deleted the fix/eol-churn-numstat-detection branch August 1, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install-update Installer, updater, packaging, wheels, doctor comp/cli CLI entry point, hermes_cli/, setup wizard duplicate This issue or pull request already exists P2 Medium — degraded but workaround exists platform/windows Native Windows-specific behavior or breakage sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants