|
@@ -1245,3 +1245,59 @@ def commit_tree_changes(object_store, tree, changes):
|
|
|
tree[name] = (stat.S_IFDIR, subtree.id)
|
|
|
object_store.add_object(tree)
|
|
|
return tree
|
|
|
+
|
|
|
+
|
|
|
+class OverlayObjectStore(BaseObjectStore):
|
|
|
+ """Object store that can overlay multiple object stores."""
|
|
|
+
|
|
|
+ def __init__(self, bases, add_store=None):
|
|
|
+ self.bases = bases
|
|
|
+ self.add_store = add_store
|
|
|
+
|
|
|
+ def add_object(self, object):
|
|
|
+ if self.add_store is None:
|
|
|
+ raise NotImplementedError(self.add_object)
|
|
|
+ return self.add_store.add_object(object)
|
|
|
+
|
|
|
+ def add_objects(self, objects):
|
|
|
+ if self.add_store is None:
|
|
|
+ raise NotImplementedError(self.add_object)
|
|
|
+ return self.add_store.add_objects(objects)
|
|
|
+
|
|
|
+ @property
|
|
|
+ def packs(self):
|
|
|
+ ret = []
|
|
|
+ for b in self.bases:
|
|
|
+ ret.extend(b.packs)
|
|
|
+ return ret
|
|
|
+
|
|
|
+ def __iter__(self):
|
|
|
+ done = set()
|
|
|
+ for b in self.bases:
|
|
|
+ for o_id in b:
|
|
|
+ if o_id not in done:
|
|
|
+ yield o_id
|
|
|
+ done.add(o_id)
|
|
|
+
|
|
|
+ def get_raw(self, sha_id):
|
|
|
+ for b in self.bases:
|
|
|
+ try:
|
|
|
+ return b.get_raw(sha_id)
|
|
|
+ except KeyError:
|
|
|
+ pass
|
|
|
+ else:
|
|
|
+ raise KeyError(sha_id)
|
|
|
+
|
|
|
+ def contains_packed(self, sha):
|
|
|
+ for b in self.bases:
|
|
|
+ if b.contains_packed(sha):
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def contains_loose(self, sha):
|
|
|
+ for b in self.bases:
|
|
|
+ if b.contains_loose(sha):
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ return False
|