30
30
except ImportError:
35
from bzrlib.diff import show_diff_trees
33
from bzrlib import osutils
34
from bzrlib.diff import show_diff_trees, internal_diff
36
35
from bzrlib.errors import NoSuchFile
37
36
from bzrlib.trace import warning
210
209
def set_trees(self, rev_tree, parent_tree):
211
210
self.rev_tree = rev_tree
212
211
self.parent_tree = parent_tree
212
# self._build_delta()
214
# def _build_delta(self):
215
# self.parent_tree.lock_read()
216
# self.rev_tree.lock_read()
218
# self.delta = _iter_changes_to_status(self.parent_tree, self.rev_tree)
219
# self.path_to_status = {}
220
# self.path_to_diff = {}
221
# source_inv = self.parent_tree.inventory
222
# target_inv = self.rev_tree.inventory
223
# for (file_id, real_path, change_type, display_path) in self.delta:
224
# self.path_to_status[real_path] = u'=== %s %s' % (change_type, display_path)
225
# if change_type in ('modified', 'renamed and modified'):
226
# source_ie = source_inv[file_id]
227
# target_ie = target_inv[file_id]
229
# source_ie.diff(internal_diff, *old path, *old_tree,
230
# *new_path, target_ie, self.rev_tree,
232
# self.path_to_diff[real_path] =
235
# self.rev_tree.unlock()
236
# self.parent_tree.unlock()
214
238
def show_diff(self, specific_files):
220
244
# contents as getdefaultencoding(), so we should
221
245
# probably try to make the paths in the same encoding.
223
self.buffer.set_text(s.getvalue().decode(sys.getdefaultencoding(), 'replace'))
247
# str.decode(encoding, 'replace') doesn't do anything. Because if a
248
# character is not valid in 'encoding' there is nothing to replace, the
249
# 'replace' is for 'str.encode()'
251
decoded = s.getvalue().decode(sys.getdefaultencoding())
252
except UnicodeDecodeError:
254
decoded = s.getvalue().decode('UTF-8')
255
except UnicodeDecodeError:
256
decoded = s.getvalue().decode('iso-8859-1')
257
# This always works, because every byte has a valid
258
# mapping from iso-8859-1 to Unicode
259
# TextBuffer must contain pure UTF-8 data
260
self.buffer.set_text(decoded.encode('UTF-8'))
226
263
class DiffWindow(gtk.Window):
342
379
specific_files = None
344
381
self.diff_view.show_diff(specific_files)
384
def _iter_changes_to_status(source, target):
385
"""Determine the differences between trees.
387
This is a wrapper around _iter_changes which just yields more
388
understandable results.
390
:param source: The source tree (basis tree)
391
:param target: The target tree
392
:return: A list of (file_id, real_path, change_type, display_path)
397
renamed_and_modified = 'renamed and modified'
398
modified = 'modified'
399
kind_changed = 'kind changed'
401
# TODO: Handle metadata changes
408
for (file_id, paths, changed_content, versioned, parent_ids, names,
409
kinds, executables) in target._iter_changes(source):
411
# Skip the root entry if it isn't very interesting
412
if parent_ids == (None, None):
419
source_marker = osutils.kind_marker(kinds[0])
421
assert kinds[0] is not None
422
marker = osutils.kind_marker(kinds[0])
424
marker = osutils.kind_marker(kinds[1])
427
if real_path is None:
429
assert real_path is not None
430
display_path = real_path + marker
432
present_source = versioned[0] and kinds[0] is not None
433
present_target = versioned[1] and kinds[1] is not None
435
if present_source != present_target:
439
assert present_source
440
change_type = removed
441
elif names[0] != names[1] or parent_ids[0] != parent_ids[1]:
443
if changed_content or executables[0] != executables[1]:
445
change_type = renamed_and_modified
447
change_type = renamed
448
display_path = (paths[0] + source_marker
449
+ ' => ' + paths[1] + marker)
450
elif kinds[0] != kinds[1]:
451
change_type = kind_changed
452
display_path = (paths[0] + source_marker
453
+ ' => ' + paths[1] + marker)
454
elif changed_content is True or executables[0] != executables[1]:
455
change_type = modified
457
assert False, "How did we get here?"
459
status.append((file_id, real_path, change_type, display_path))