diff --git a/hgext/record.py b/hgext/record.py --- a/hgext/record.py +++ b/hgext/record.py @@ -10,65 +10,12 @@ from mercurial.i18n import _ from mercurial import cmdutil, commands, extensions, hg, patch from mercurial import util -import copy, cStringIO, errno, os, re, shutil, tempfile +import copy, cStringIO, errno, os, shutil, tempfile cmdtable = {} command = cmdutil.command(cmdtable) testedwith = 'internal' -lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)') - -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)) - """ - lr = patch.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 parsepatch(fp): """patch -> [] of headers -> [] of hunks """ @@ -93,7 +40,7 @@ def parsepatch(fp): def addcontext(self, context): if self.hunk: h = patch.recordhunk(self.header, self.fromline, self.toline, - self.proc, self.before, self.hunk, context) + self.proc, self.before, self.hunk, context) self.header.hunks.append(h) self.fromline += len(self.before) + h.removed self.toline += len(self.before) + h.added @@ -141,7 +88,7 @@ def parsepatch(fp): p = parser() state = 'context' - for newstate, data in scanpatch(fp): + for newstate, data in patch.scanpatch(fp): try: p.transitions[state][newstate](p, data) except KeyError: diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -1276,6 +1276,58 @@ def makepatchmeta(backend, afile_orig, b 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: