15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
from bzrlib.trace import mutter
19
from bzrlib.errors import BzrError
20
from bzrlib.delta import compare_trees
18
from trace import mutter
19
from errors import BzrError
22
# TODO: Rather than building a changeset object, we should probably
23
# invoke callbacks on an object. That object can either accumulate a
24
# list, write them out directly, etc etc.
26
22
def internal_diff(old_label, oldlines, new_label, newlines, to_file):
249
class TreeDelta(object):
250
"""Describes changes from one tree to another.
259
(oldpath, newpath, id, kind, text_modified)
265
Each id is listed only once.
267
Files that are both modified and renamed are listed only in
268
renamed, with the text_modified flag true.
270
The lists are normally sorted when the delta is created.
280
def touches_file_id(self, file_id):
281
"""Return True if file_id is modified by this delta."""
282
for l in self.added, self.removed, self.modified:
286
for v in self.renamed:
292
def show(self, to_file, show_ids=False, show_unchanged=False):
293
def show_list(files):
294
for path, fid, kind in files:
295
if kind == 'directory':
297
elif kind == 'symlink':
301
print >>to_file, ' %-30s %s' % (path, fid)
303
print >>to_file, ' ', path
306
print >>to_file, 'removed:'
307
show_list(self.removed)
310
print >>to_file, 'added:'
311
show_list(self.added)
314
print >>to_file, 'renamed:'
315
for oldpath, newpath, fid, kind, text_modified in self.renamed:
317
print >>to_file, ' %s => %s %s' % (oldpath, newpath, fid)
319
print >>to_file, ' %s => %s' % (oldpath, newpath)
322
print >>to_file, 'modified:'
323
show_list(self.modified)
325
if show_unchanged and self.unchanged:
326
print >>to_file, 'unchanged:'
327
show_list(self.unchanged)
331
def compare_trees(old_tree, new_tree, want_unchanged, specific_files=None):
332
"""Describe changes from one tree to another.
334
Returns a TreeDelta with details of added, modified, renamed, and
337
The root entry is specifically exempt.
339
This only considers versioned files.
342
If true, also list files unchanged from one version to
346
If true, only check for changes to specified names or
350
from osutils import is_inside_any
352
old_inv = old_tree.inventory
353
new_inv = new_tree.inventory
355
mutter('start compare_trees')
357
# TODO: match for specific files can be rather smarter by finding
358
# the IDs of those files up front and then considering only that.
360
for file_id in old_tree:
361
if file_id in new_tree:
362
kind = old_inv.get_file_kind(file_id)
363
assert kind == new_inv.get_file_kind(file_id)
365
assert kind in ('file', 'directory', 'symlink', 'root_directory'), \
366
'invalid file kind %r' % kind
368
if kind == 'root_directory':
371
old_path = old_inv.id2path(file_id)
372
new_path = new_inv.id2path(file_id)
375
if (not is_inside_any(specific_files, old_path)
376
and not is_inside_any(specific_files, new_path)):
380
old_sha1 = old_tree.get_file_sha1(file_id)
381
new_sha1 = new_tree.get_file_sha1(file_id)
382
text_modified = (old_sha1 != new_sha1)
384
## mutter("no text to check for %r %r" % (file_id, kind))
385
text_modified = False
387
# TODO: Can possibly avoid calculating path strings if the
388
# two files are unchanged and their names and parents are
389
# the same and the parents are unchanged all the way up.
390
# May not be worthwhile.
392
if old_path != new_path:
393
delta.renamed.append((old_path, new_path, file_id, kind,
396
delta.modified.append((new_path, file_id, kind))
398
delta.unchanged.append((new_path, file_id, kind))
400
kind = old_inv.get_file_kind(file_id)
401
old_path = old_inv.id2path(file_id)
403
if not is_inside_any(specific_files, old_path):
405
delta.removed.append((old_path, file_id, kind))
407
mutter('start looking for new files')
408
for file_id in new_inv:
409
if file_id in old_inv:
411
new_path = new_inv.id2path(file_id)
413
if not is_inside_any(specific_files, new_path):
415
kind = new_inv.get_file_kind(file_id)
416
delta.added.append((new_path, file_id, kind))
421
delta.modified.sort()
422
delta.unchanged.sort()