482
482
def _patch_header_date(tree, file_id, path):
483
483
"""Returns a timestamp suitable for use in a patch header."""
485
mtime = tree.get_file_mtime(file_id, path)
485
mtime = tree.get_file_mtime(path, file_id)
486
486
except FileTimestampUnavailable:
488
488
return timestamp.format_patch_date(mtime)
602
602
if 'symlink' not in (old_kind, new_kind):
603
603
return self.CANNOT_DIFF
604
604
if old_kind == 'symlink':
605
old_target = self.old_tree.get_symlink_target(file_id)
605
old_target = self.old_tree.get_symlink_target(old_path, file_id)
606
606
elif old_kind is None:
607
607
old_target = None
609
609
return self.CANNOT_DIFF
610
610
if new_kind == 'symlink':
611
new_target = self.new_tree.get_symlink_target(file_id)
611
new_target = self.new_tree.get_symlink_target(new_path, file_id)
612
612
elif new_kind is None:
613
613
new_target = None
670
670
return self.CANNOT_DIFF
671
671
from_label = '%s%s\t%s' % (self.old_label, old_path, old_date)
672
672
to_label = '%s%s\t%s' % (self.new_label, new_path, new_date)
673
return self.diff_text(from_file_id, to_file_id, from_label, to_label,
673
return self.diff_text(old_path, new_path, from_label, to_label,
674
from_file_id, to_file_id)
676
def diff_text(self, from_file_id, to_file_id, from_label, to_label,
677
from_path=None, to_path=None):
676
def diff_text(self, from_path, to_path, from_label, to_label,
677
from_file_id=None, to_file_id=None):
678
678
"""Diff the content of given files in two trees
680
:param from_file_id: The id of the file in the from tree. If None,
680
:param from_path: The path in the from tree. If None,
681
681
the file is not present in the from tree.
682
:param to_file_id: The id of the file in the to tree. This may refer
683
to a different file from from_file_id. If None,
682
:param to_path: The path in the to tree. This may refer
683
to a different file from from_path. If None,
684
684
the file is not present in the to tree.
685
:param from_path: The path in the from tree or None if unknown.
686
:param to_path: The path in the to tree or None if unknown.
685
:param from_file_id: The id of the file in the from tree or None if
687
:param to_file_id: The id of the file in the to tree or None if
688
690
def _get_text(tree, file_id, path):
689
if file_id is not None:
690
return tree.get_file_lines(file_id, path)
693
return tree.get_file_lines(path, file_id)
694
695
from_text = _get_text(self.old_tree, from_file_id, from_path)
695
696
to_text = _get_text(self.new_tree, to_file_id, to_path)
797
798
relpath_tmp = relpath_tmp.replace(u'?', u'_')
798
799
return osutils.pathjoin(self._root, prefix, relpath_tmp)
800
def _write_file(self, file_id, tree, prefix, relpath, force_temp=False,
801
def _write_file(self, relpath, tree, prefix, force_temp=False,
802
allow_write=False, file_id=None):
802
803
if not force_temp and isinstance(tree, WorkingTree):
803
full_path = tree.abspath(tree.id2path(file_id))
804
full_path = tree.abspath(relpath)
804
805
if self._is_safepath(full_path):
832
833
osutils.make_readonly(full_path)
835
def _prepare_files(self, file_id, old_path, new_path, force_temp=False,
836
allow_write_new=False):
837
old_disk_path = self._write_file(file_id, self.old_tree, 'old',
838
old_path, force_temp)
839
new_disk_path = self._write_file(file_id, self.new_tree, 'new',
840
new_path, force_temp,
836
def _prepare_files(self, old_path, new_path, force_temp=False,
837
allow_write_new=False, file_id=None):
838
old_disk_path = self._write_file(old_path, self.old_tree, 'old',
839
force_temp, file_id=file_id)
840
new_disk_path = self._write_file(new_path, self.new_tree, 'new',
841
force_temp, file_id=file_id,
841
842
allow_write=allow_write_new)
842
843
return old_disk_path, new_disk_path
853
854
if (old_kind, new_kind) != ('file', 'file'):
854
855
return DiffPath.CANNOT_DIFF
855
856
(old_disk_path, new_disk_path) = self._prepare_files(
856
file_id, old_path, new_path)
857
old_path, new_path, file_id=file_id)
857
858
self._execute(old_disk_path, new_disk_path)
859
def edit_file(self, file_id):
860
def edit_file(self, old_path, new_path, file_id=None):
860
861
"""Use this tool to edit a file.
862
863
A temporary copy will be edited, and the new contents will be
865
866
:param file_id: The id of the file to edit.
866
867
:return: The new contents of the file.
868
old_path = self.old_tree.id2path(file_id)
869
new_path = self.new_tree.id2path(file_id)
870
869
old_abs_path, new_abs_path = self._prepare_files(
871
file_id, old_path, new_path,
872
allow_write_new=True,
870
old_path, new_path, allow_write_new=True, force_temp=True,
874
872
command = self._get_command(old_abs_path, new_abs_path)
875
873
subprocess.call(command, cwd=self._root)
876
874
new_file = open(new_abs_path, 'rb')
1025
1023
self.to_file.write("=== modified %s '%s'%s\n" % (kind[0],
1026
1024
newpath_encoded, prop_str))
1027
1025
if changed_content:
1028
self._diff(file_id, oldpath, newpath, kind[0], kind[1])
1026
self._diff(oldpath, newpath, kind[0], kind[1], file_id=file_id)
1029
1027
has_changes = 1
1031
1029
has_changes = 1
1038
1036
:param old_path: The path of the file in the old tree
1039
1037
:param new_path: The path of the file in the new tree
1042
old_kind = self.old_tree.kind(file_id)
1043
except (errors.NoSuchId, errors.NoSuchFile):
1039
if old_path is None:
1044
1040
old_kind = None
1046
new_kind = self.new_tree.kind(file_id)
1047
except (errors.NoSuchId, errors.NoSuchFile):
1042
old_kind = self.old_tree.kind(old_path, file_id)
1043
if new_path is None:
1048
1044
new_kind = None
1049
self._diff(file_id, old_path, new_path, old_kind, new_kind)
1052
def _diff(self, file_id, old_path, new_path, old_kind, new_kind):
1046
new_kind = self.new_tree.kind(new_path, file_id)
1047
self._diff(old_path, new_path, old_kind, new_kind, file_id=file_id)
1049
def _diff(self, old_path, new_path, old_kind, new_kind, file_id):
1053
1050
result = DiffPath._diff_many(self.differs, file_id, old_path,
1054
1051
new_path, old_kind, new_kind)
1055
1052
if result is DiffPath.CANNOT_DIFF: