Fix interdiff post-processing with replace chunks overflowing ranges.
Review Request #6030 — Created June 25, 2014 and submitted
When post-processing interdiffs in order to filter out unrelated code,
we had issues where replace chunks could be generated where its
orig/modified ranges weren't equal. This would trigger an assert, which
is probably good, because removing the assert resulted in a
corrupted-looking diff.This same sort of bug could also affect equal chunks in theory, though
in practice, they weren't in as bad a situation.The reason this was failing was that we attempted to cap each range to
the chunk's boundaries, without any regard to whether or not the lengths
needed to be consistent.Now, for equal and replace chunks, we get the lengths of the
orig/modified ranges for the chunk, figure out the longest of the two,
cap that within the valid range boundary, and use that as the end
positions for the chunk.This ensures that we only show the replace/equal range for the section
represented in the union of the two diffs. Anything else outside of that
will turn into a filtered-equal.I added a new unit test that previously broke but is fixed with this
change. However, I then noticed that another unit test broke. Turns out,
it was already broken. It had resulting replace/equal chunks that didn't
have consistent ranges, and chunks overflowing the bounds. After looking
at the original chunks and throwing away the unit test's bad resulting
chunks, I created a new set based on what they should have been. This
ended up matching the results of the unit test.I added some new sanity-checking in the unit tests to make sure that any
opcode lists we provide in the future will meet certain criteria, to
help catch such issues in the future.
All unit tests pass, including the fixed version of another test (which has
results computed by hand and not copied/pasted from the results).Tested with a series of interdiffs I had laying around, and with some broken
interdiffs that were identified.
-
A new diff added to the existing review is now causing the following diff viewer error:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/views.py", line 236, in get
renderer = self.create_renderer(context, args, kwargs)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/reviews/views.py", line 1102, in create_renderer
args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/views.py", line 326, in create_renderer
self.diff_file = self._get_requested_diff_file()
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/views.py", line 367, in _get_requested_diff_file
request=self.request)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/diffutils.py", line 373, in populate_diff_chunks
chunks = generator.get_chunks()
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/chunk_generator.py", line 148, in get_chunks
large_data=True)
File "/usr/local/lib/python2.7/dist-packages/Djblets-0.8.2-py2.7.egg/djblets/cache/backend.py", line 109, in cache_memoize
data = lookup_callable()
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/chunk_generator.py", line 147, in <lambda>
lambda: list(self._get_chunks_uncached()),
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/chunk_generator.py", line 253, in _get_chunks_uncached
for tag, i1, i2, j1, j2, meta in opcodes_generator:
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/opcode_generator.py", line 70, in iter
self._group_opcodes(opcodes)
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/opcode_generator.py", line 141, in _group_opcodes
for group_index, group in enumerate(opcodes):
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/opcode_generator.py", line 137, in _apply_meta_processors
for opcode in opcodes:
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/processors.py", line 214, in post_process_filtered_equals
for tag, i1, i2, j1, j2, meta in opcodes:
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/opcode_generator.py", line 87, in _generate_opcode_meta
for tag, i1, i2, j1, j2 in opcodes:
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/opcode_generator.py", line 83, in _apply_processors
for opcode in opcodes:
File "/usr/local/lib/python2.7/dist-packages/ReviewBoard-2.0.1-py2.7.egg/reviewboard/diffviewer/processors.py", line 125, in filter_interdiff_opcodes
cap_i2 = orig_range[1] + 1
TypeError: 'NoneType' object has no attribute 'getitem'
- Change Summary:
-
Fixed issues with replace and equal lines when one side starts past its diff's last range.
- Commit:
-
617f432b03102a5e80d67b50884c46ed3ffb91bf44201b8a2284514123cc906057cf0ced0f85f752