~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: Aaron Bentley
  • Date: 2006-09-20 14:03:05 UTC
  • mto: This revision was merged to the branch mainline in revision 2162.
  • Revision ID: abentley@panoramicfeedback.com-20060920140305-7726fe3eb92690b1
Get tree._iter_changed down to ~ 1 stat per file

Show diffs side-by-side

added added

removed removed

Lines of Context:
150
150
    def kind(self, file_id):
151
151
        raise NotImplementedError("subclasses must implement kind")
152
152
 
 
153
    def _comparison_data(self, entry, path):
 
154
        raise NotImplementedError(self._comparison_data)
 
155
 
 
156
    def _file_size(entry, stat_value):
 
157
        raise NotImplementedError(self._file_size)
 
158
 
153
159
    def _get_inventory(self):
154
160
        return self._inventory
155
161
    
247
253
    def __contains__(self, file_id):
248
254
        return (file_id in self._inventory)
249
255
 
250
 
    def get_file_sha1(self, file_id, path=None):
 
256
    def get_file_sha1(self, file_id, path=None, stat_value=None):
251
257
        return None
252
258
 
253
259
 
460
466
        to_paths = {}
461
467
        if specific_file_ids is not None:
462
468
            specific_file_ids = set(specific_file_ids)
463
 
        for path, to_entry in to_tree.iter_entries_by_dir():
 
469
        from_entries_by_dir = list(from_tree.iter_entries_by_dir())
 
470
        from_data = dict((e.file_id, (p, e)) for p, e in from_entries_by_dir)
 
471
        for to_path, to_entry in to_tree.iter_entries_by_dir():
464
472
            file_id = to_entry.file_id
465
 
            to_paths[file_id] = path
 
473
            to_paths[file_id] = to_path
466
474
            if (specific_file_ids is not None and 
467
475
                file_id not in specific_file_ids):
468
476
                continue
469
477
            changed_content = False
470
 
            from_versioned = (file_id in from_tree)
471
 
            versioned = (from_versioned, True)
472
 
            if from_versioned:
473
 
                from_kind = get_versioned_kind(from_tree, file_id)
474
 
                if from_kind is not None:
475
 
                    from_executable = (from_tree.is_executable(file_id) not in 
476
 
                                       (False, None))
477
 
                else:
478
 
                    from_executable = None
479
 
                from_entry = from_tree.inventory[file_id]
 
478
            from_path, from_entry = from_data.get(file_id, (None, None))
 
479
            from_versioned = (from_entry is not None)
 
480
            if from_entry is not None:
 
481
                from_versioned = True
 
482
                from_name = from_entry.name
480
483
                from_parent = from_entry.parent_id
481
 
                from_name = from_entry.name
 
484
                from_kind, from_executable, from_stat = \
 
485
                    from_tree._comparison_data(from_entry, from_path)
482
486
            else:
 
487
                from_versioned = False
483
488
                from_kind = None
484
489
                from_parent = None
485
490
                from_name = None
486
491
                from_executable = None
487
 
            to_kind = get_versioned_kind(to_tree, file_id)
 
492
            versioned = (from_versioned, True)
 
493
            to_kind, to_executable, to_stat = \
 
494
                to_tree._comparison_data(to_entry, to_path)
488
495
            kind = (from_kind, to_kind)
489
496
            if kind[0] != kind[1]:
490
497
                changed_content = True
491
498
            elif from_kind == 'file':
492
 
                if (from_tree.get_file_sha1(file_id) !=
493
 
                    to_tree.get_file_sha1(file_id)):
 
499
                from_size = from_tree._file_size(from_entry, from_stat)
 
500
                to_size = to_tree._file_size(to_entry, to_stat)
 
501
                if from_size != to_size:
 
502
                    changed_content = True
 
503
                elif (from_tree.get_file_sha1(file_id, from_path, from_stat) !=
 
504
                    to_tree.get_file_sha1(file_id, to_path, to_stat)):
494
505
                    changed_content = True
495
506
            elif from_kind == 'symlink':
496
507
                if (from_tree.get_symlink_target(file_id) != 
498
509
                    changed_content = True
499
510
            parent = (from_parent, to_entry.parent_id)
500
511
            name = (from_name, to_entry.name)
501
 
            if to_kind is not None:
502
 
                to_executable = (to_tree.is_executable(file_id) not in 
503
 
                                 (False, None))
504
 
            else:
505
 
                to_executable = None
506
512
            executable = (from_executable, to_executable)
507
513
            if (changed_content is not False or versioned[0] != versioned[1] 
508
514
                or parent[0] != parent[1] or name[0] != name[1] or 
509
515
                executable[0] != executable[1] or include_unchanged):
510
 
                yield (file_id, path, changed_content, versioned, parent,
 
516
                yield (file_id, to_path, changed_content, versioned, parent,
511
517
                       name, kind, executable)
512
518
 
513
 
        for path, from_entry in from_tree.iter_entries_by_dir():
 
519
        for path, from_entry in from_entries_by_dir:
514
520
            file_id = from_entry.file_id
515
521
            if file_id in to_paths:
516
522
                continue
523
529
            versioned = (True, False)
524
530
            parent = (from_entry.parent_id, None)
525
531
            name = (from_entry.name, None)
526
 
            kind = (get_versioned_kind(from_tree, file_id), None)
527
 
            if kind[0] is not None:
528
 
                from_executable = (from_tree.is_executable(file_id) not in 
529
 
                                   (False, None))
530
 
            else:
531
 
                from_executable = False
 
532
            from_kind, from_executable, stat_value = \
 
533
                from_tree._comparison_data(from_entry, path)
 
534
            kind = (from_kind, None)
532
535
            executable = (from_executable, None)
533
536
            changed_content = True
534
537
            # the parent's path is necessarily known at this point.