~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/patches.py

  • Committer: Gordon Tyler
  • Date: 2009-11-11 21:38:02 UTC
  • mto: This revision was merged to the branch mainline in revision 4801.
  • Revision ID: gordon@doxxx.net-20091111213802-wj8d2fgirjd7saqn
Fixed globbing.normalize_pattern to not strip '/' down to '' and normalize multiple slashes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Aaron Bentley, Canonical Ltd
 
1
# Copyright (C) 2004 - 2006, 2008 Aaron Bentley, Canonical Ltd
2
2
# <aaron.bentley@utoronto.ca>
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
17
17
import re
18
18
 
19
19
 
20
 
binary_files_re = 'Binary files (.*) and (.*) differ\n'
21
 
 
22
 
 
23
20
class BinaryFiles(Exception):
24
21
 
25
22
    def __init__(self, orig_name, mod_name):
69
66
def get_patch_names(iter_lines):
70
67
    try:
71
68
        line = iter_lines.next()
72
 
        match = re.match(binary_files_re, line)
 
69
        match = re.match('Binary files (.*) and (.*) differ\n', line)
73
70
        if match is not None:
74
71
            raise BinaryFiles(match.group(1), match.group(2))
75
72
        if not line.startswith("--- "):
250
247
        return shift
251
248
 
252
249
 
253
 
def iter_hunks(iter_lines, allow_dirty=False):
254
 
    '''
255
 
    :arg iter_lines: iterable of lines to parse for hunks
256
 
    :kwarg allow_dirty: If True, when we encounter something that is not
257
 
        a hunk header when we're looking for one, assume the rest of the lines
258
 
        are not part of the patch (comments or other junk).  Default False
259
 
    '''
 
250
def iter_hunks(iter_lines):
260
251
    hunk = None
261
252
    for line in iter_lines:
262
253
        if line == "\n":
266
257
            continue
267
258
        if hunk is not None:
268
259
            yield hunk
269
 
        try:
270
 
            hunk = hunk_from_header(line)
271
 
        except MalformedHunkHeader:
272
 
            if allow_dirty:
273
 
                # If the line isn't a hunk header, then we've reached the end
274
 
                # of this patch and there's "junk" at the end.  Ignore the
275
 
                # rest of this patch.
276
 
                return
277
 
            raise
 
260
        hunk = hunk_from_header(line)
278
261
        orig_size = 0
279
262
        mod_size = 0
280
263
        while orig_size < hunk.orig_range or mod_size < hunk.mod_range:
353
336
                    pos += 1
354
337
 
355
338
 
356
 
def parse_patch(iter_lines, allow_dirty=False):
357
 
    '''
358
 
    :arg iter_lines: iterable of lines to parse
359
 
    :kwarg allow_dirty: If True, allow the patch to have trailing junk.
360
 
        Default False
361
 
    '''
 
339
def parse_patch(iter_lines):
362
340
    iter_lines = iter_lines_handle_nl(iter_lines)
363
341
    try:
364
342
        (orig_name, mod_name) = get_patch_names(iter_lines)
366
344
        return BinaryPatch(e.orig_name, e.mod_name)
367
345
    else:
368
346
        patch = Patch(orig_name, mod_name)
369
 
        for hunk in iter_hunks(iter_lines, allow_dirty):
 
347
        for hunk in iter_hunks(iter_lines):
370
348
            patch.hunks.append(hunk)
371
349
        return patch
372
350
 
373
351
 
374
 
def iter_file_patch(iter_lines, allow_dirty=False):
375
 
    '''
376
 
    :arg iter_lines: iterable of lines to parse for patches
377
 
    :kwarg allow_dirty: If True, allow comments and other non-patch text
378
 
        before the first patch.  Note that the algorithm here can only find
379
 
        such text before any patches have been found.  Comments after the
380
 
        first patch are stripped away in iter_hunks() if it is also passed
381
 
        allow_dirty=True.  Default False.
382
 
    '''
383
 
    ### FIXME: Docstring is not quite true.  We allow certain comments no
384
 
    # matter what, If they startwith '===', '***', or '#' Someone should
385
 
    # reexamine this logic and decide if we should include those in
386
 
    # allow_dirty or restrict those to only being before the patch is found
387
 
    # (as allow_dirty does).
388
 
    regex = re.compile(binary_files_re)
 
352
def iter_file_patch(iter_lines):
389
353
    saved_lines = []
390
354
    orig_range = 0
391
 
    beginning = True
392
355
    for line in iter_lines:
393
356
        if line.startswith('=== ') or line.startswith('*** '):
394
357
            continue
397
360
        elif orig_range > 0:
398
361
            if line.startswith('-') or line.startswith(' '):
399
362
                orig_range -= 1
400
 
        elif line.startswith('--- ') or regex.match(line):
401
 
            if allow_dirty and beginning:
402
 
                # Patches can have "junk" at the beginning
403
 
                # Stripping junk from the end of patches is handled when we
404
 
                # parse the patch
405
 
                beginning = False
406
 
            elif len(saved_lines) > 0:
 
363
        elif line.startswith('--- '):
 
364
            if len(saved_lines) > 0:
407
365
                yield saved_lines
408
366
            saved_lines = []
409
367
        elif line.startswith('@@'):
435
393
        yield last_line
436
394
 
437
395
 
438
 
def parse_patches(iter_lines, allow_dirty=False):
439
 
    '''
440
 
    :arg iter_lines: iterable of lines to parse for patches
441
 
    :kwarg allow_dirty: If True, allow text that's not part of the patch at
442
 
        selected places.  This includes comments before and after a patch
443
 
        for instance.  Default False.
444
 
    '''
445
 
    return [parse_patch(f.__iter__(), allow_dirty) for f in
446
 
                        iter_file_patch(iter_lines, allow_dirty)]
 
396
def parse_patches(iter_lines):
 
397
    return [parse_patch(f.__iter__()) for f in iter_file_patch(iter_lines)]
447
398
 
448
399
 
449
400
def difference_index(atext, btext):