in jobs/webcompat-kb/webcompat_kb/metric_changes.py [0:0]
def reverse_apply_diff(input_str: str, diff: str) -> str:
"""Apply a diff in reverse to get the original string"""
input_lines = input_str.splitlines(True)
input_idx = 0
diff_lines = diff.splitlines(True)
diff_idx = 0
output_lines = []
while diff_idx < len(diff_lines):
m = header_pattern.match(diff_lines[diff_idx])
if m is None:
raise ValueError(f"Bad user story diff (missing header line):\n{diff}")
start_line_number = int(m.group(3))
end_line_number = int(m.group(4)) if m.group(4) else None
start_idx = max(start_line_number - 1, 0)
if start_idx < input_idx or (
end_line_number is not None and end_line_number > len(input_lines)
):
raise ValueError(f"Bad user story diff (index out of bounds):\n{diff}")
output_lines.extend(input_lines[input_idx:start_idx])
diff_idx += 1
input_idx = start_idx
while diff_idx < len(diff_lines) and diff_lines[diff_idx][0] != "@":
change_char = diff_lines[diff_idx][0]
data = diff_lines[diff_idx][1:]
if change_char == "+":
input_idx += 1
elif change_char == " ":
if input_lines[input_idx].strip() != data.strip():
raise ValueError(
f"Bad user story diff (patch doesn't match):\n{diff}\nInput line {input_idx} expected {data} got {input_lines[input_idx]}"
)
output_lines.append(data)
input_idx += 1
else:
output_lines.append(data)
diff_idx += 1
output_lines.extend(input_lines[input_idx:])
return "".join(output_lines)