Mercurial > public > mercurial-scm > hg-stable
diff mercurial/patch.py @ 24264:c4205452f1b7
record: move scanpatch from record to patch
Part of a series of patches to move record from hgext to core
author | Laurent Charignon <lcharignon@fb.com> |
---|---|
date | Mon, 09 Mar 2015 13:14:31 -0700 |
parents | a45d1c51109e |
children | dc655360bccb |
line wrap: on
line diff
--- a/mercurial/patch.py Mon Mar 09 13:09:15 2015 -0700 +++ b/mercurial/patch.py Mon Mar 09 13:14:31 2015 -0700 @@ -1276,6 +1276,58 @@ gp.op = 'DELETE' return gp +def scanpatch(fp): + """like patch.iterhunks, but yield different events + + - ('file', [header_lines + fromfile + tofile]) + - ('context', [context_lines]) + - ('hunk', [hunk_lines]) + - ('range', (-start,len, +start,len, proc)) + """ + lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)') + lr = linereader(fp) + + def scanwhile(first, p): + """scan lr while predicate holds""" + lines = [first] + while True: + line = lr.readline() + if not line: + break + if p(line): + lines.append(line) + else: + lr.push(line) + break + return lines + + while True: + line = lr.readline() + if not line: + break + if line.startswith('diff --git a/') or line.startswith('diff -r '): + def notheader(line): + s = line.split(None, 1) + return not s or s[0] not in ('---', 'diff') + header = scanwhile(line, notheader) + fromfile = lr.readline() + if fromfile.startswith('---'): + tofile = lr.readline() + header += [fromfile, tofile] + else: + lr.push(fromfile) + yield 'file', header + elif line[0] == ' ': + yield 'context', scanwhile(line, lambda l: l[0] in ' \\') + elif line[0] in '-+': + yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\') + else: + m = lines_re.match(line) + if m: + yield 'range', m.groups() + else: + yield 'other', line + def scangitpatch(lr, firstline): """ Git patches can emit: