736
745
return self.CHANGED
748
class DiffFromTool(DiffPath):
750
def __init__(self, command_template, old_tree, new_tree, to_file,
751
path_encoding='utf-8'):
752
DiffPath.__init__(self, old_tree, new_tree, to_file, path_encoding)
753
self.command_template = command_template
754
self._root = tempfile.mkdtemp(prefix='bzr-diff-')
757
def from_string(klass, command_string, old_tree, new_tree, to_file,
758
path_encoding='utf-8'):
759
command_template = commands.shlex_split_unicode(command_string)
760
command_template.extend(['%(old_path)s', '%(new_path)s'])
761
return klass(command_template, old_tree, new_tree, to_file,
765
def make_from_diff_tree(klass, command_string):
766
def from_diff_tree(diff_tree):
767
return klass.from_string(command_string, diff_tree.old_tree,
768
diff_tree.new_tree, diff_tree.to_file)
769
return from_diff_tree
771
def _get_command(self, old_path, new_path):
772
my_map = {'old_path': old_path, 'new_path': new_path}
773
return [t % my_map for t in self.command_template]
775
def _execute(self, old_path, new_path):
776
proc = subprocess.Popen(self._get_command(old_path, new_path),
777
stdout=subprocess.PIPE, cwd=self._root)
778
self.to_file.write(proc.stdout.read())
781
def _write_file(self, file_id, tree, prefix, old_path):
782
full_old_path = osutils.pathjoin(self._root, prefix, old_path)
783
parent_dir = osutils.dirname(full_old_path)
785
os.makedirs(parent_dir)
787
if e.errno != errno.EEXIST:
789
source = tree.get_file(file_id)
791
target = open(full_old_path, 'wb')
793
osutils.pumpfile(source, target)
800
def _prepare_files(self, file_id, old_path, new_path):
801
old_disk_path = self._write_file(file_id, self.old_tree, 'old',
803
new_disk_path = self._write_file(file_id, self.new_tree, 'new',
805
return old_disk_path, new_disk_path
808
shutil.rmtree(self._root)
810
def diff(self, file_id, old_path, new_path, old_kind, new_kind):
811
if (old_kind, new_kind) != ('file', 'file'):
812
return DiffPath.CANNOT_DIFF
813
self._prepare_files(file_id, old_path, new_path)
814
self._execute(osutils.pathjoin('old', old_path),
815
osutils.pathjoin('new', new_path))
739
818
class DiffTree(object):
740
819
"""Provides textual representations of the difference between two trees.
803
887
diff_file = internal_diff
804
888
diff_text = DiffText(old_tree, new_tree, to_file, path_encoding,
805
889
old_label, new_label, diff_file)
806
return klass(old_tree, new_tree, to_file, path_encoding, diff_text)
890
return klass(old_tree, new_tree, to_file, path_encoding, diff_text,
808
893
def show_diff(self, specific_files, extra_trees=None):
809
894
"""Write tree diff to self.to_file
811
896
:param sepecific_files: the specific files to compare (recursive)
812
897
:param extra_trees: extra trees to use for mapping paths to file_ids
900
return self._show_diff(specific_files, extra_trees)
902
for differ in self.differs:
905
def _show_diff(self, specific_files, extra_trees):
814
906
# TODO: Generation of pseudo-diffs for added/deleted files could
815
907
# be usefully made into a much faster special case.
816
908
iterator = self.new_tree._iter_changes(self.old_tree,