Skip to content

Instantly share code, notes, and snippets.

@fridgei
Created December 20, 2013 21:16
Show Gist options
  • Save fridgei/8061665 to your computer and use it in GitHub Desktop.
Save fridgei/8061665 to your computer and use it in GitHub Desktop.
import re
diff_re = re.compile(
"@@ \-(?P<removed_start>\d+),(?P<removed_length>\d+) "
"\+(?P<added_start>\d+),(?P<added_length>\d+) @@"
)
class DiffContext:
def __init__(self, lines, path):
self.lines = lines
self.path = path
class DiffContextParser:
def __init__(self, diff_text):
self.diff_text = diff_text
def parse(self):
before_contexts, after_contexts = [], []
lines_before, lines_after = [], []
before_line_number, after_line_number = 0, 0
before_path = after_path = ''
position = 0
for line in self.diff_text.splitlines()[2:]:
header = diff_re.search(line)
if header is not None:
before_line_number = int(header.group('removed_start'))
after_line_number = int(header.group('added_start'))
if lines_before:
before_contexts.append(DiffContext(lines_before, before_path))
before_lines = []
if lines_after:
after_contexts.append(DiffContext(lines_after, after_path))
after_lines = []
continue
elif line.startswith('---'):
before_path = line[5:]
continue
elif line.startswith('+++'):
after_path = line[5:]
continue
position += 1
if line.startswith('-'):
lines_before.append((before_line_number, position, line[1:]))
before_line_number += 1
elif line.startswith('+'):
lines_after.append((before_line_number, position, line[1:]))
after_line_number += 1
else:
lines_before.append((before_line_number, position, line))
lines_after.append((after_line_number, position, line))
before_line_number += 1
after_line_number += 1
if before_lines:
before_contexts.append(DiffContext(lines_before, before_path))
if after_lines:
after_contexts.append(DiffContext(lines_after, after_path))
return before_contexts, after_contexts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment