Commits (3)
  • Brandon Maier's avatar
    Fix missing diff output on large diffs. · 6790469f
    Brandon Maier authored and Chris Lamb's avatar Chris Lamb committed
    When there is a large diff chunk, match_lines() will skip running the
    difflib.Differ.compare(). However this causes the following issues:
    
    - It does not empty the `self.buf` buffer. This means that all future
      calls to match_lines() for that file will always be too large. So
      effectively no more diffs from the file get output.
    
    - It outputs a debug message, but does not output anything to the
      side-by-side diff, so a user looking at the side-by-side diff may be
      misled into thinking the rest of the file has no differences.
    
    We can fix these issue by falling back to a lazy line-by-line diff. This
    produces suboptimal output, but it runs in linear O(n) time while
    providing some form of output. We include a comment in the diff so the
    user knows the following output is using a lazy diff algorithm.
    6790469f
  • Chris Lamb's avatar
    Apply Black to previous commit. · 11cdb97c
    Chris Lamb authored
    Gbp-dch: ignore
    11cdb97c
  • Chris Lamb's avatar
    Import itertools top-level directly. · 592c401b
    Chris Lamb authored
    Gbp-dch: ignore
    592c401b
......@@ -24,6 +24,7 @@ import errno
import fcntl
import hashlib
import logging
import itertools
import threading
import subprocess
......@@ -551,11 +552,11 @@ class SideBySideDiff:
if len(l0) + len(l1) > 750:
# difflib.Differ.compare is at least O(n^2), so don't call it if
# our inputs are too large.
logger.debug(
"Not calling difflib.Differ.compare(x, y) with len(x) == %d and len(y) == %d",
len(l0),
len(l1),
yield "C", "Diff chunk too large, falling back to line-by-line diff ({} lines added, {} lines removed)".format(
self.add_cpt, self.del_cpt
)
for line0, line1 in itertools.zip_longest(l0, l1, fillvalue=""):
yield from self.yield_line(line0, line1)
return
saved_line = None
......