@@ -739,6 +739,11 @@ def _apply_patch(self, path: str, cwd: str, diff: str, ctx: ToolContext) -> str:
739739
740740
741741_HUNK_HEADER_RE = re .compile (r"^@@ -(\d+),(\d+) +\+(\d+),(\d+) @@" )
742+ # A file section's header pair: the marker must be followed by whitespace
743+ # (real headers name a path), which content lines rendered ---/+++ by the
744+ # diff itself normally are not.
745+ _FILE_HEADER_OLD_RE = re .compile (r"^---[ \t]" )
746+ _FILE_HEADER_NEW_RE = re .compile (r"^\+\+\+[ \t]" )
742747
743748
744749def _strip_diff_fence (text : str ) -> str :
@@ -782,9 +787,7 @@ def _fix_patch_headers(diff_text: str) -> str:
782787 body : list [str ] = []
783788 while j < n and not lines [j ].startswith ("@@" ):
784789 line = lines [j ]
785- if (line .startswith ("---" ) or line .startswith ("+++" )) and _starts_file_section (
786- lines , j
787- ):
790+ if line .startswith ("---" ) and _starts_file_section (lines , j ):
788791 # A ---/+++ pair introducing the next file; not hunk body.
789792 break
790793 if line .startswith ("-" ):
@@ -805,16 +808,31 @@ def _fix_patch_headers(diff_text: str) -> str:
805808def _starts_file_section (lines : list [str ], idx : int ) -> bool :
806809 """Whether lines[idx] begins the next file's ---/+++ header pair.
807810
808- A new file section in a multi-file diff is ``--- path`` / ``+++ path``
809- immediately followed by a hunk header. Removed/added content lines
810- whose text merely starts with ``--``/``++`` (rendered ``---``/``+++``)
811- are hunk body and must be counted; peeking for the trailing ``@@``
812- tells the two apart.
811+ A new file section in a multi-file diff is ``--- path`` immediately
812+ followed by ``+++ path`` and then a hunk header. Removed/added
813+ content lines whose text merely starts with ``--``/``++`` (rendered
814+ ``---``/``+++``) are hunk body and must be counted, so all three
815+ parts are required:
816+
817+ * the ordered pair — a lone ``---``-rendered content line as a
818+ hunk's LAST body line is followed directly by the next hunk
819+ header, which a peek for a trailing ``@@`` alone cannot tell from
820+ a file header (it silently dropped the line from the count and
821+ made `patch` reject the whole diff);
822+ * the space/tab after the marker — real headers carry a path
823+ (``--- a/f``), content lines usually do not (``---removed``);
824+ * the trailing hunk header.
825+
826+ A hunk whose last two body lines happen to be a removed line
827+ starting with ``-- `` AND an added line starting with ``++ `` is
828+ still indistinguishable from a file header pair by shape alone; it
829+ stays a known (and far rarer) miscount.
813830 """
814- k = idx
815- while k < len (lines ) and (lines [k ].startswith ("---" ) or lines [k ].startswith ("+++" )):
816- k += 1
817- return k < len (lines ) and lines [k ].startswith ("@@" )
831+ if not _FILE_HEADER_OLD_RE .match (lines [idx ]):
832+ return False
833+ if idx + 1 >= len (lines ) or not _FILE_HEADER_NEW_RE .match (lines [idx + 1 ]):
834+ return False
835+ return idx + 2 < len (lines ) and lines [idx + 2 ].startswith ("@@" )
818836
819837
820838class Insert (Tool ):
0 commit comments