"""
raise NotImplementedError(self.add_objects)
+ def tree_changes(self, source, target, want_unchanged=False):
+ """Find the differences between the contents of two trees
+
+ :param object_store: Object store to use for retrieving tree contents
+ :param tree: SHA1 of the root tree
+ :param want_unchanged: Whether unchanged files should be reported
+ :return: Iterator over tuples with (oldpath, newpath), (oldmode, newmode), (oldsha, newsha)
+ """
+ todo = set([(source, target, "")])
+ while todo:
+ (sid, tid, path) = todo.pop()
+ if sid is not None:
+ stree = self[sid]
+ else:
+ stree = {}
+ if tid is not None:
+ ttree = self[tid]
+ else:
+ ttree = {}
+ for name, oldmode, oldhexsha in stree.iteritems():
+ if path == "":
+ oldchildpath = name
+ else:
+ oldchildpath = "%s/%s" % (path, name)
+ try:
+ (newmode, newhexsha) = ttree[name]
+ newchildpath = oldchildpath
+ except KeyError:
+ newmode = None
+ newhexsha = None
+ newchildpath = None
+ if (want_unchanged or oldmode != newmode or
+ oldhexsha != newhexsha):
+ if stat.S_ISDIR(oldmode):
+ if newmode is None or stat.S_ISDIR(newmode):
+ todo.add((oldhexsha, newhexsha, oldchildpath))
+ else:
+ # entry became a file
+ todo.add((oldhexsha, None, oldchildpath))
+ yield ((None, newchildpath), (None, newmode), (None, newhexsha))
+ else:
+ if newmode is not None and stat.S_ISDIR(newmode):
+ # entry became a dir
+ yield ((oldchildpath, None), (oldmode, None), (oldhexsha, None))
+ todo.add((None, newhexsha, newchildpath))
+ else:
+ yield ((oldchildpath, newchildpath), (oldmode, newmode), (oldhexsha, newhexsha))
+
+ for name, newmode, newhexsha in ttree.iteritems():
+ if path == "":
+ childpath = name
+ else:
+ childpath = "%s/%s" % (path, name)
+ if not name in stree:
+ if not stat.S_ISDIR(newmode):
+ yield ((None, childpath), (None, newmode), (None, newhexsha))
+ else:
+ todo.add((None, newhexsha, childpath))
+
def iter_tree_contents(self, tree):
"""Yield (path, mode, hexsha) tuples for all non-Tree objects in a tree.