814
814
# TODO: Generation of pseudo-diffs for added/deleted files could
815
815
# be usefully made into a much faster special case.
817
delta = self.new_tree.changes_from(self.old_tree,
818
specific_files=specific_files,
819
extra_trees=extra_trees, require_versioned=True)
816
iterator = self.new_tree._iter_changes(self.old_tree,
817
specific_files=specific_files,
818
extra_trees=extra_trees,
819
require_versioned=True)
822
for path, file_id, kind in delta.removed:
824
path_encoded = path.encode(self.path_encoding, "replace")
825
self.to_file.write("=== removed %s '%s'\n" % (kind, path_encoded))
826
self.diff(file_id, path, path)
828
for path, file_id, kind in delta.added:
830
path_encoded = path.encode(self.path_encoding, "replace")
831
self.to_file.write("=== added %s '%s'\n" % (kind, path_encoded))
832
self.diff(file_id, path, path)
833
for (old_path, new_path, file_id, kind,
834
text_modified, meta_modified) in delta.renamed:
836
prop_str = get_prop_change(meta_modified)
837
oldpath_encoded = old_path.encode(self.path_encoding, "replace")
838
newpath_encoded = new_path.encode(self.path_encoding, "replace")
839
self.to_file.write("=== renamed %s '%s' => '%s'%s\n" % (kind,
840
oldpath_encoded, newpath_encoded, prop_str))
842
self.diff(file_id, old_path, new_path)
843
for path, file_id, kind, text_modified, meta_modified in\
846
prop_str = get_prop_change(meta_modified)
847
path_encoded = path.encode(self.path_encoding, "replace")
848
self.to_file.write("=== modified %s '%s'%s\n" % (kind,
849
path_encoded, prop_str))
850
# The file may be in a different location in the old tree (because
851
# the containing dir was renamed, but the file itself was not)
853
old_path = self.old_tree.id2path(file_id)
854
self.diff(file_id, old_path, path)
821
def changes_key(change):
822
old_path, new_path = change[1]
827
def get_encoded_path(path):
829
return path.encode(self.path_encoding, "replace")
830
for (file_id, paths, changed_content, versioned, parent, name, kind,
831
executable) in sorted(iterator, key=changes_key):
832
oldpath_encoded = get_encoded_path(paths[0])
833
newpath_encoded = get_encoded_path(paths[1])
834
old_present = (kind[0] is not None and versioned[0])
835
new_present = (kind[1] is not None and versioned[1])
836
renamed = (parent[0], name[0]) != (parent[1], name[1])
837
prop_str = get_prop_change(executable[0] != executable[1])
838
if (old_present, new_present) == (True, False):
839
self.to_file.write("=== removed %s '%s'\n" %
840
(kind[0], oldpath_encoded))
841
elif (old_present, new_present) == (False, True):
842
self.to_file.write("=== added %s '%s'\n" %
843
(kind[1], newpath_encoded))
845
self.to_file.write("=== renamed %s '%s' => '%s'%s\n" %
846
(kind[0], oldpath_encoded, newpath_encoded, prop_str))
847
elif changed_content:
848
self.to_file.write("=== modified %s '%s'%s\n" % (kind[0],
849
newpath_encoded, prop_str))
851
self.diff(file_id, paths[0], paths[1])
855
855
return has_changes
857
857
def diff(self, file_id, old_path, new_path):