diff --git a/hermes_cli/update_cmd.py b/hermes_cli/update_cmd.py index d5e1c445f4..95982c0f28 100644 --- a/hermes_cli/update_cmd.py +++ b/hermes_cli/update_cmd.py @@ -3474,8 +3474,36 @@ def _normalize_managed_eol(git_cmd, repo_root): return None return {p for p in out.stdout.split("\0") if p} + def _real_dirty(): + # Files with a *content* change once CRLF differences are ignored. + # NOTE: ``diff --name-only --ignore-cr-at-eol`` still LISTS CR-only + # files (the name list is computed from blob/stat differences before + # the CR filter is applied), so it cannot be used to isolate real + # edits. ``--numstat`` does honor the filter: a CR-only file produces + # no numstat record, while a genuinely-edited file does. Parse the + # paths out of numstat instead. + out = subprocess.run( + probe + ["-c", "core.quotepath=false", + "diff", "--numstat", "--ignore-cr-at-eol"], + cwd=repo_root, + capture_output=True, + text=True, encoding="utf-8", errors="replace", + ) + if out.returncode != 0: + return None + paths = set() + for line in out.stdout.splitlines(): + if not line.strip(): + continue + # Format: "\t\t". Rename detection is off in + # plain diff, so there is exactly one path field per record. + parts = line.split("\t", 2) + if len(parts) == 3 and parts[2]: + paths.add(parts[2]) + return paths + def _eol_only(): - all_dirty, real_dirty = _dirty(), _dirty("--ignore-cr-at-eol") + all_dirty, real_dirty = _dirty(), _real_dirty() if all_dirty is None or real_dirty is None: return None return all_dirty - real_dirty