~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/diff.py

  • Committer: Martin Pool
  • Date: 2005-06-22 06:37:43 UTC
  • Revision ID: mbp@sourcefrog.net-20050622063743-e395f04c4db8977f
- move old blackbox code from testbzr into bzrlib.selftest.blackbox

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
from errors import BzrError
20
20
 
21
21
 
22
 
# TODO: Rather than building a changeset object, we should probably
23
 
# invoke callbacks on an object.  That object can either accumulate a
24
 
# list, write them out directly, etc etc.
25
 
 
26
22
def internal_diff(old_label, oldlines, new_label, newlines, to_file):
27
23
    import difflib
28
24
    
42
38
    if not oldlines and not newlines:
43
39
        return
44
40
 
 
41
    nonl = False
 
42
 
 
43
    if oldlines and (oldlines[-1][-1] != '\n'):
 
44
        oldlines[-1] += '\n'
 
45
        nonl = True
 
46
    if newlines and (newlines[-1][-1] != '\n'):
 
47
        newlines[-1] += '\n'
 
48
        nonl = True
 
49
 
45
50
    ud = difflib.unified_diff(oldlines, newlines,
46
51
                              fromfile=old_label, tofile=new_label)
47
52
 
54
59
        ud = list(ud)
55
60
        ud[2] = ud[2].replace('+1,0', '+0,0')
56
61
 
57
 
    for line in ud:
58
 
        to_file.write(line)
59
 
        if not line.endswith('\n'):
60
 
            to_file.write("\n\\ No newline at end of file\n")
 
62
    to_file.writelines(ud)
 
63
    if nonl:
 
64
        print >>to_file, "\\ No newline at end of file"
61
65
    print >>to_file
62
66
 
63
67
 
263
267
    Files that are both modified and renamed are listed only in
264
268
    renamed, with the text_modified flag true.
265
269
 
266
 
    Files are only considered renamed if their name has changed or
267
 
    their parent directory has changed.  Renaming a directory
268
 
    does not count as renaming all its contents.
269
 
 
270
270
    The lists are normally sorted when the delta is created.
271
271
    """
272
272
    def __init__(self):
276
276
        self.modified = []
277
277
        self.unchanged = []
278
278
 
279
 
    def __eq__(self, other):
280
 
        if not isinstance(other, TreeDelta):
281
 
            return False
282
 
        return self.added == other.added \
283
 
               and self.removed == other.removed \
284
 
               and self.renamed == other.renamed \
285
 
               and self.modified == other.modified \
286
 
               and self.unchanged == other.unchanged
287
 
 
288
 
    def __ne__(self, other):
289
 
        return not (self == other)
290
 
 
291
279
    def __repr__(self):
292
280
        return "TreeDelta(added=%r, removed=%r, renamed=%r, modified=%r," \
293
281
            " unchanged=%r)" % (self.added, self.removed, self.renamed,
349
337
 
350
338
 
351
339
 
352
 
def compare_trees(old_tree, new_tree, want_unchanged=False, specific_files=None):
 
340
def compare_trees(old_tree, new_tree, want_unchanged, specific_files=None):
353
341
    """Describe changes from one tree to another.
354
342
 
355
343
    Returns a TreeDelta with details of added, modified, renamed, and
380
368
 
381
369
    for file_id in old_tree:
382
370
        if file_id in new_tree:
383
 
            old_ie = old_inv[file_id]
384
 
            new_ie = new_inv[file_id]
385
 
 
386
 
            kind = old_ie.kind
387
 
            assert kind == new_ie.kind
 
371
            kind = old_inv.get_file_kind(file_id)
 
372
            assert kind == new_inv.get_file_kind(file_id)
388
373
            
389
374
            assert kind in ('file', 'directory', 'symlink', 'root_directory'), \
390
375
                   'invalid file kind %r' % kind
392
377
            if kind == 'root_directory':
393
378
                continue
394
379
            
 
380
            old_path = old_inv.id2path(file_id)
 
381
            new_path = new_inv.id2path(file_id)
 
382
 
395
383
            if specific_files:
396
 
                if (not is_inside_any(specific_files, old_inv.id2path(file_id)) 
397
 
                    and not is_inside_any(specific_files, new_inv.id2path(file_id))):
 
384
                if (not is_inside_any(specific_files, old_path) 
 
385
                    and not is_inside_any(specific_files, new_path)):
398
386
                    continue
399
387
 
400
388
            if kind == 'file':
410
398
            # the same and the parents are unchanged all the way up.
411
399
            # May not be worthwhile.
412
400
            
413
 
            if (old_ie.name != new_ie.name
414
 
                or old_ie.parent_id != new_ie.parent_id):
415
 
                delta.renamed.append((old_inv.id2path(file_id),
416
 
                                      new_inv.id2path(file_id),
417
 
                                      file_id, kind,
 
401
            if old_path != new_path:
 
402
                delta.renamed.append((old_path, new_path, file_id, kind,
418
403
                                      text_modified))
419
404
            elif text_modified:
420
 
                delta.modified.append((new_inv.id2path(file_id), file_id, kind))
 
405
                delta.modified.append((new_path, file_id, kind))
421
406
            elif want_unchanged:
422
 
                delta.unchanged.append((new_inv.id2path(file_id), file_id, kind))
 
407
                delta.unchanged.append((new_path, file_id, kind))
423
408
        else:
424
409
            kind = old_inv.get_file_kind(file_id)
425
410
            old_path = old_inv.id2path(file_id)