634
635
path in the specific_files list is not versioned in one of
635
636
source, target or extra_trees.
637
lookup_trees = [self.source]
639
lookup_trees.extend(extra_trees)
640
specific_file_ids = self.target.paths2ids(specific_files,
641
lookup_trees, require_versioned=require_versioned)
643
from_entries_by_dir = list(self.source.inventory.iter_entries_by_dir(
644
specific_file_ids=specific_file_ids))
645
from_data = dict((e.file_id, (p, e)) for p, e in from_entries_by_dir)
646
to_entries_by_dir = list(self.target.inventory.iter_entries_by_dir(
647
specific_file_ids=specific_file_ids))
648
num_entries = len(from_entries_by_dir) + len(to_entries_by_dir)
650
for to_path, to_entry in to_entries_by_dir:
651
file_id = to_entry.file_id
652
to_paths[file_id] = to_path
654
changed_content = False
655
from_path, from_entry = from_data.get(file_id, (None, None))
656
from_versioned = (from_entry is not None)
657
if from_entry is not None:
658
from_versioned = True
659
from_name = from_entry.name
660
from_parent = from_entry.parent_id
661
from_kind, from_executable, from_stat = \
662
self.source._comparison_data(from_entry, from_path)
665
from_versioned = False
669
from_executable = None
670
versioned = (from_versioned, True)
671
to_kind, to_executable, to_stat = \
672
self.target._comparison_data(to_entry, to_path)
673
kind = (from_kind, to_kind)
674
if kind[0] != kind[1]:
638
# this must return a sequence rather than a list so that it can hold a
639
# read-lock for the whole time.
641
# TODO: this really only needs to lock the trees not the branches, so
642
# could do with lock_tree_read() -- mbp 20070227
644
self.source.lock_read()
645
self.target.lock_read()
647
lookup_trees = [self.source]
649
lookup_trees.extend(extra_trees)
650
specific_file_ids = self.target.paths2ids(specific_files,
651
lookup_trees, require_versioned=require_versioned)
653
from_entries_by_dir = list(self.source.inventory.iter_entries_by_dir(
654
specific_file_ids=specific_file_ids))
655
from_data = dict((e.file_id, (p, e)) for p, e in from_entries_by_dir)
656
to_entries_by_dir = list(self.target.inventory.iter_entries_by_dir(
657
specific_file_ids=specific_file_ids))
658
num_entries = len(from_entries_by_dir) + len(to_entries_by_dir)
660
for to_path, to_entry in to_entries_by_dir:
661
file_id = to_entry.file_id
662
to_paths[file_id] = to_path
664
changed_content = False
665
from_path, from_entry = from_data.get(file_id, (None, None))
666
from_versioned = (from_entry is not None)
667
if from_entry is not None:
668
from_versioned = True
669
from_name = from_entry.name
670
from_parent = from_entry.parent_id
671
from_kind, from_executable, from_stat = \
672
self.source._comparison_data(from_entry, from_path)
675
from_versioned = False
679
from_executable = None
680
versioned = (from_versioned, True)
681
to_kind, to_executable, to_stat = \
682
self.target._comparison_data(to_entry, to_path)
683
kind = (from_kind, to_kind)
684
if kind[0] != kind[1]:
685
changed_content = True
686
elif from_kind == 'file':
687
from_size = self.source._file_size(from_entry, from_stat)
688
to_size = self.target._file_size(to_entry, to_stat)
689
if from_size != to_size:
690
changed_content = True
691
elif (self.source.get_file_sha1(file_id, from_path, from_stat) !=
692
self.target.get_file_sha1(file_id, to_path, to_stat)):
693
changed_content = True
694
elif from_kind == 'symlink':
695
if (self.source.get_symlink_target(file_id) !=
696
self.target.get_symlink_target(file_id)):
697
changed_content = True
698
elif from_kind == 'tree-reference':
699
if (self.source.get_reference_revision(from_entry, from_path)
700
!= self.target.get_reference_revision(to_entry, to_path)):
701
changed_content = True
702
parent = (from_parent, to_entry.parent_id)
703
name = (from_name, to_entry.name)
704
executable = (from_executable, to_executable)
706
pb.update('comparing files', entry_count, num_entries)
707
if (changed_content is not False or versioned[0] != versioned[1]
708
or parent[0] != parent[1] or name[0] != name[1] or
709
executable[0] != executable[1] or include_unchanged):
710
result.append((file_id, to_path, changed_content, versioned, parent,
711
name, kind, executable))
712
def get_to_path(from_entry):
713
if from_entry.parent_id is None:
716
if from_entry.parent_id not in to_paths:
717
get_to_path(self.source.inventory[from_entry.parent_id])
718
to_path = osutils.pathjoin(to_paths[from_entry.parent_id],
720
to_paths[from_entry.file_id] = to_path
723
for path, from_entry in from_entries_by_dir:
724
file_id = from_entry.file_id
725
if file_id in to_paths:
727
to_path = get_to_path(from_entry)
730
pb.update('comparing files', entry_count, num_entries)
731
versioned = (True, False)
732
parent = (from_entry.parent_id, None)
733
name = (from_entry.name, None)
734
from_kind, from_executable, stat_value = \
735
self.source._comparison_data(from_entry, path)
736
kind = (from_kind, None)
737
executable = (from_executable, None)
675
738
changed_content = True
676
elif from_kind == 'file':
677
from_size = self.source._file_size(from_entry, from_stat)
678
to_size = self.target._file_size(to_entry, to_stat)
679
if from_size != to_size:
680
changed_content = True
681
elif (self.source.get_file_sha1(file_id, from_path, from_stat) !=
682
self.target.get_file_sha1(file_id, to_path, to_stat)):
683
changed_content = True
684
elif from_kind == 'symlink':
685
if (self.source.get_symlink_target(file_id) !=
686
self.target.get_symlink_target(file_id)):
687
changed_content = True
688
elif from_kind == 'tree-reference':
689
if (self.source.get_reference_revision(from_entry, from_path)
690
!= self.target.get_reference_revision(to_entry, to_path)):
691
changed_content = True
692
parent = (from_parent, to_entry.parent_id)
693
name = (from_name, to_entry.name)
694
executable = (from_executable, to_executable)
696
pb.update('comparing files', entry_count, num_entries)
697
if (changed_content is not False or versioned[0] != versioned[1]
698
or parent[0] != parent[1] or name[0] != name[1] or
699
executable[0] != executable[1] or include_unchanged):
700
yield (file_id, to_path, changed_content, versioned, parent,
701
name, kind, executable)
703
def get_to_path(from_entry):
704
if from_entry.parent_id is None:
707
if from_entry.parent_id not in to_paths:
708
get_to_path(self.source.inventory[from_entry.parent_id])
709
to_path = osutils.pathjoin(to_paths[from_entry.parent_id],
711
to_paths[from_entry.file_id] = to_path
714
for path, from_entry in from_entries_by_dir:
715
file_id = from_entry.file_id
716
if file_id in to_paths:
718
to_path = get_to_path(from_entry)
721
pb.update('comparing files', entry_count, num_entries)
722
versioned = (True, False)
723
parent = (from_entry.parent_id, None)
724
name = (from_entry.name, None)
725
from_kind, from_executable, stat_value = \
726
self.source._comparison_data(from_entry, path)
727
kind = (from_kind, None)
728
executable = (from_executable, None)
729
changed_content = True
730
# the parent's path is necessarily known at this point.
731
yield(file_id, to_path, changed_content, versioned, parent,
732
name, kind, executable)
739
# the parent's path is necessarily known at this point.
740
result.append((file_id, to_path, changed_content, versioned, parent,
741
name, kind, executable))
735
749
# This was deprecated before 0.12, but did not have an official warning