736
747
return self.CHANGED
750
class DiffFromTool(DiffPath):
752
def __init__(self, command_template, old_tree, new_tree, to_file,
753
path_encoding='utf-8'):
754
DiffPath.__init__(self, old_tree, new_tree, to_file, path_encoding)
755
self.command_template = command_template
756
self._root = tempfile.mkdtemp(prefix='bzr-diff-')
759
def from_string(klass, command_string, old_tree, new_tree, to_file,
760
path_encoding='utf-8'):
761
command_template = commands.shlex_split_unicode(command_string)
762
command_template.extend(['%(old_path)s', '%(new_path)s'])
763
return klass(command_template, old_tree, new_tree, to_file,
767
def make_from_diff_tree(klass, command_string):
768
def from_diff_tree(diff_tree):
769
return klass.from_string(command_string, diff_tree.old_tree,
770
diff_tree.new_tree, diff_tree.to_file)
771
return from_diff_tree
773
def _get_command(self, old_path, new_path):
774
my_map = {'old_path': old_path, 'new_path': new_path}
775
return [t % my_map for t in self.command_template]
777
def _execute(self, old_path, new_path):
778
command = self._get_command(old_path, new_path)
780
proc = subprocess.Popen(command, stdout=subprocess.PIPE,
783
if e.errno == errno.ENOENT:
784
raise errors.ExecutableMissing(command[0])
787
self.to_file.write(proc.stdout.read())
790
def _try_symlink_root(self, tree, prefix):
791
if not (getattr(tree, 'abspath', None) is not None
792
and osutils.has_symlinks()):
795
os.symlink(tree.abspath(''), osutils.pathjoin(self._root, prefix))
797
if e.errno != errno.EEXIST:
801
def _write_file(self, file_id, tree, prefix, relpath):
802
full_path = osutils.pathjoin(self._root, prefix, relpath)
803
if self._try_symlink_root(tree, prefix):
805
parent_dir = osutils.dirname(full_path)
807
os.makedirs(parent_dir)
809
if e.errno != errno.EEXIST:
811
source = tree.get_file(file_id, relpath)
813
target = open(full_path, 'wb')
815
osutils.pumpfile(source, target)
820
osutils.make_readonly(full_path)
821
mtime = tree.get_file_mtime(file_id)
822
os.utime(full_path, (mtime, mtime))
825
def _prepare_files(self, file_id, old_path, new_path):
826
old_disk_path = self._write_file(file_id, self.old_tree, 'old',
828
new_disk_path = self._write_file(file_id, self.new_tree, 'new',
830
return old_disk_path, new_disk_path
833
osutils.rmtree(self._root)
835
def diff(self, file_id, old_path, new_path, old_kind, new_kind):
836
if (old_kind, new_kind) != ('file', 'file'):
837
return DiffPath.CANNOT_DIFF
838
self._prepare_files(file_id, old_path, new_path)
839
self._execute(osutils.pathjoin('old', old_path),
840
osutils.pathjoin('new', new_path))
739
843
class DiffTree(object):
740
844
"""Provides textual representations of the difference between two trees.
803
912
diff_file = internal_diff
804
913
diff_text = DiffText(old_tree, new_tree, to_file, path_encoding,
805
914
old_label, new_label, diff_file)
806
return klass(old_tree, new_tree, to_file, path_encoding, diff_text)
915
return klass(old_tree, new_tree, to_file, path_encoding, diff_text,
808
918
def show_diff(self, specific_files, extra_trees=None):
809
919
"""Write tree diff to self.to_file