150
150
def kind(self, file_id):
151
151
raise NotImplementedError("subclasses must implement kind")
153
def _comparison_data(self, entry, path):
154
raise NotImplementedError(self._comparison_data)
156
def _file_size(entry, stat_value):
157
raise NotImplementedError(self._file_size)
153
159
def _get_inventory(self):
154
160
return self._inventory
247
253
def __contains__(self, file_id):
248
254
return (file_id in self._inventory)
250
def get_file_sha1(self, file_id, path=None):
256
def get_file_sha1(self, file_id, path=None, stat_value=None):
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):
469
477
changed_content = False
470
from_versioned = (file_id in from_tree)
471
versioned = (from_versioned, True)
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
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)
487
from_versioned = False
484
489
from_parent = 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
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)
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:
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
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.