577
577
"""Generate an iterator of changes between trees.
579
579
A tuple is returned:
580
(file_id, path, changed_content, versioned, parent, name, kind,
580
(file_id, (path_in_source, path_in_target),
581
changed_content, versioned, parent, name, kind,
583
Path is relative to the target tree. changed_content is True if the
584
file's content has changed. This includes changes to its kind, and to
584
Changed_content is True if the file's content has changed. This
585
includes changes to its kind, and to a symlink's target.
587
587
versioned, parent, name, kind, executable are tuples of (from, to).
588
588
If a file is missing in a tree, its kind is None.
630
630
unversioned_path = all_unversioned.popleft()
631
631
to_kind, to_executable, to_stat = \
632
632
self.target._comparison_data(fake_entry, unversioned_path[1])
633
yield (None, unversioned_path[1], True, (False, False),
633
yield (None, (None, unversioned_path[1]), True, (False, False),
635
635
(None, unversioned_path[0][-1]),
680
680
if (changed_content is not False or versioned[0] != versioned[1]
681
681
or parent[0] != parent[1] or name[0] != name[1] or
682
682
executable[0] != executable[1] or include_unchanged):
683
yield (file_id, to_path, changed_content, versioned, parent,
684
name, kind, executable)
683
yield (file_id, (from_path, to_path), changed_content,
684
versioned, parent, name, kind, executable)
685
686
while all_unversioned:
686
687
# yield any trailing unversioned paths
687
688
unversioned_path = all_unversioned.popleft()
688
689
to_kind, to_executable, to_stat = \
689
690
self.target._comparison_data(fake_entry, unversioned_path[1])
690
yield (None, unversioned_path[1], True, (False, False),
691
yield (None, (None, unversioned_path[1]), True, (False, False),
692
693
(None, unversioned_path[0][-1]),
694
695
(None, to_executable))
696
def get_to_path(from_entry):
697
if from_entry.parent_id is None:
697
def get_to_path(to_entry):
698
if to_entry.parent_id is None:
699
to_path = '' # the root
700
if from_entry.parent_id not in to_paths:
701
get_to_path(self.source.inventory[from_entry.parent_id])
702
to_path = osutils.pathjoin(to_paths[from_entry.parent_id],
704
to_paths[from_entry.file_id] = to_path
701
if to_entry.parent_id not in to_paths:
703
return get_to_path(self.target.inventory[to_entry.parent_id])
704
to_path = osutils.pathjoin(to_paths[to_entry.parent_id],
706
to_paths[to_entry.file_id] = to_path
707
709
for path, from_entry in from_entries_by_dir:
708
710
file_id = from_entry.file_id
709
711
if file_id in to_paths:
711
to_path = get_to_path(from_entry)
714
if not file_id in self.target.inventory:
715
# common case - paths we have not emitted are not present in
719
to_path = get_to_path(self.target.inventory[file_id])
713
721
if pb is not None:
714
722
pb.update('comparing files', entry_count, num_entries)
721
729
executable = (from_executable, None)
722
730
changed_content = True
723
731
# the parent's path is necessarily known at this point.
724
yield(file_id, to_path, changed_content, versioned, parent,
732
yield(file_id, (path, to_path), changed_content, versioned, parent,
725
733
name, kind, executable)