13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
43
42
from bzrlib.symbol_versioning import (
46
from bzrlib.trace import mutter, note, warning
46
from bzrlib.trace import mutter, warning
49
49
# TODO: Rather than building a changeset object, we should probably
78
78
# both sequences are empty.
79
79
if not oldlines and not newlines:
82
82
if allow_binary is False:
83
83
textfile.check_text_lines(oldlines)
84
84
textfile.check_text_lines(newlines)
99
99
ud[2] = ud[2].replace('-1,0', '-0,0')
100
100
elif not newlines:
101
101
ud[2] = ud[2].replace('+1,0', '+0,0')
102
# work around for difflib emitting random spaces after the label
103
ud[0] = ud[0][:-2] + '\n'
104
ud[1] = ud[1][:-2] + '\n'
104
107
to_file.write(line)
201
204
diffcmd.append('-u')
204
207
diffcmd.extend(diff_opts)
206
209
pipe = _spawn_external_diff(diffcmd, capture_errors=True)
207
210
out,err = pipe.communicate()
208
211
rc = pipe.returncode
210
213
# internal_diff() adds a trailing newline, add one here for consistency
275
def _get_trees_to_diff(path_list, revision_specs, old_url, new_url,
278
def _get_trees_to_diff(path_list, revision_specs, old_url, new_url):
277
279
"""Get the trees and specific files to diff given a list of paths.
279
281
This method works out the trees to be diff'ed and the files of
291
293
The url of the new branch or tree. If None, the tree to use is
292
294
taken from the first path, if any, or the current working tree.
294
if True and a view is set, apply the view or check that the paths
297
296
a tuple of (old_tree, new_tree, specific_files, extra_trees) where
298
297
extra_trees is a sequence of additional trees to search in for
332
331
working_tree, branch, relpath = \
333
332
bzrdir.BzrDir.open_containing_tree_or_branch(old_url)
334
333
if consider_relpath and relpath != '':
335
if working_tree is not None and apply_view:
336
views.check_path_in_view(working_tree, relpath)
337
334
specific_files.append(relpath)
338
335
old_tree = _get_tree_to_diff(old_revision_spec, working_tree, branch)
344
341
working_tree, branch, relpath = \
345
342
bzrdir.BzrDir.open_containing_tree_or_branch(new_url)
346
343
if consider_relpath and relpath != '':
347
if working_tree is not None and apply_view:
348
views.check_path_in_view(working_tree, relpath)
349
344
specific_files.append(relpath)
350
345
new_tree = _get_tree_to_diff(new_revision_spec, working_tree, branch,
351
346
basis_is_default=working_tree is None)
353
348
# Get the specific files (all files is None, no files is [])
354
349
if make_paths_wt_relative and working_tree is not None:
356
from bzrlib.builtins import safe_relpath_files
357
other_paths = safe_relpath_files(working_tree, other_paths,
358
apply_view=apply_view)
359
except errors.FileInWrongBranch:
360
raise errors.BzrCommandError("Files are in different branches")
350
other_paths = _relative_paths_in_tree(working_tree, other_paths)
361
351
specific_files.extend(other_paths)
362
352
if len(specific_files) == 0:
363
353
specific_files = None
364
if (working_tree is not None and working_tree.supports_views()
366
view_files = working_tree.views.lookup_view()
368
specific_files = view_files
369
view_str = views.view_display_str(view_files)
370
note("*** Ignoring files outside view. View is %s" % view_str)
372
355
# Get extra trees that ought to be searched for file-ids
373
356
extra_trees = None
375
358
extra_trees = (working_tree,)
376
359
return old_tree, new_tree, specific_files, extra_trees
378
362
def _get_tree_to_diff(spec, tree=None, branch=None, basis_is_default=True):
379
363
if branch is None and tree is not None:
380
364
branch = tree.branch
386
370
return branch.basis_tree()
389
return spec.as_tree(branch)
373
if not spec.needs_branch():
374
branch = _mod_branch.Branch.open(spec.get_branch())
375
revision_id = spec.as_revision_id(branch)
376
return branch.repository.revision_tree(revision_id)
379
def _relative_paths_in_tree(tree, paths):
380
"""Get the relative paths within a working tree.
382
Each path may be either an absolute path or a path relative to the
383
current working directory.
386
for filename in paths:
388
result.append(tree.relpath(osutils.dereference_path(filename)))
389
except errors.PathNotChild:
390
raise errors.BzrCommandError("Files are in different branches")
392
394
def show_diff_trees(old_tree, new_tree, to_file, specific_files=None,
440
442
return timestamp.format_patch_date(mtime)
445
def _raise_if_nonexistent(paths, old_tree, new_tree):
446
"""Complain if paths are not in either inventory or tree.
448
It's OK with the files exist in either tree's inventory, or
449
if they exist in the tree but are not versioned.
451
This can be used by operations such as bzr status that can accept
452
unknown or ignored files.
454
mutter("check paths: %r", paths)
457
s = old_tree.filter_unversioned_files(paths)
458
s = new_tree.filter_unversioned_files(s)
459
s = [path for path in s if not new_tree.has_filename(path)]
461
raise errors.PathsDoNotExist(sorted(s))
464
@deprecated_function(one_three)
465
def get_prop_change(meta_modified):
467
return " (properties changed)"
443
471
def get_executable_change(old_is_x, new_is_x):
444
472
descr = { True:"+x", False:"-x", None:"??" }
445
473
if old_is_x != new_is_x:
620
648
return self.CANNOT_DIFF
621
649
from_label = '%s%s\t%s' % (self.old_label, old_path, old_date)
622
650
to_label = '%s%s\t%s' % (self.new_label, new_path, new_date)
623
return self.diff_text(from_file_id, to_file_id, from_label, to_label,
651
return self.diff_text(from_file_id, to_file_id, from_label, to_label)
626
def diff_text(self, from_file_id, to_file_id, from_label, to_label,
627
from_path=None, to_path=None):
653
def diff_text(self, from_file_id, to_file_id, from_label, to_label):
628
654
"""Diff the content of given files in two trees
630
656
:param from_file_id: The id of the file in the from tree. If None,
632
658
:param to_file_id: The id of the file in the to tree. This may refer
633
659
to a different file from from_file_id. If None,
634
660
the file is not present in the to tree.
635
:param from_path: The path in the from tree or None if unknown.
636
:param to_path: The path in the to tree or None if unknown.
638
def _get_text(tree, file_id, path):
662
def _get_text(tree, file_id):
639
663
if file_id is not None:
640
return tree.get_file(file_id, path).readlines()
664
return tree.get_file(file_id).readlines()
644
from_text = _get_text(self.old_tree, from_file_id, from_path)
645
to_text = _get_text(self.new_tree, to_file_id, to_path)
668
from_text = _get_text(self.old_tree, from_file_id)
669
to_text = _get_text(self.new_tree, to_file_id)
646
670
self.text_differ(from_label, from_text, to_label, to_text,
648
672
except errors.BinaryFile:
658
682
path_encoding='utf-8'):
659
683
DiffPath.__init__(self, old_tree, new_tree, to_file, path_encoding)
660
684
self.command_template = command_template
661
self._root = osutils.mkdtemp(prefix='bzr-diff-')
685
self._root = tempfile.mkdtemp(prefix='bzr-diff-')
664
688
def from_string(klass, command_string, old_tree, new_tree, to_file,
735
759
return old_disk_path, new_disk_path
737
761
def finish(self):
739
osutils.rmtree(self._root)
741
if e.errno != errno.ENOENT:
742
mutter("The temporary directory \"%s\" was not "
743
"cleanly removed: %s." % (self._root, e))
762
osutils.rmtree(self._root)
745
764
def diff(self, file_id, old_path, new_path, old_kind, new_kind):
746
765
if (old_kind, new_kind) != ('file', 'file'):
891
910
self.to_file.write("=== modified %s '%s'%s\n" % (kind[0],
892
911
newpath_encoded, prop_str))
893
912
if changed_content:
894
self._diff(file_id, oldpath, newpath, kind[0], kind[1])
913
self.diff(file_id, oldpath, newpath)
912
931
new_kind = self.new_tree.kind(file_id)
913
932
except (errors.NoSuchId, errors.NoSuchFile):
915
self._diff(file_id, old_path, new_path, old_kind, new_kind)
918
def _diff(self, file_id, old_path, new_path, old_kind, new_kind):
919
935
result = DiffPath._diff_many(self.differs, file_id, old_path,
920
936
new_path, old_kind, new_kind)
921
937
if result is DiffPath.CANNOT_DIFF: