Changeset 7a3a2de9670e…
Parent 528cbe02878d…
by
Changes to 3 files · Browse files at 7a3a2de9670e Showing diff from parent 528cbe02878d Diff from another changeset...
@@ -13,6 +13,8 @@
* ``HttpGitClient`` which supports the smart server protocol over
HTTP. "dumb" access is not yet supported. (Jelmer Vernooij, #373688)
+
+ * Add basic support for alternates. (Jelmer Vernooij, #810429)
CHANGES
|
@@ -226,6 +226,10 @@ def __init__(self):
self._pack_cache = None
+ @property
+ def alternates(self):
+ return []
+
def contains_packed(self, sha):
"""Check if a particular object is present by SHA1 and is packed."""
for pack in self.packs:
@@ -310,6 +314,11 @@ ret = self._get_loose_object(hexsha)
if ret is not None:
return ret.type_num, ret.as_raw_string()
+ for alternate in self.alternates:
+ try:
+ return alternate.get_raw(hexsha)
+ except KeyError:
+ pass
raise KeyError(hexsha)
def add_objects(self, objects):
@@ -338,6 +347,54 @@ self.path = path
self.pack_dir = os.path.join(self.path, PACKDIR)
self._pack_cache_time = 0
+ self._alternates = None
+
+ @property
+ def alternates(self):
+ if self._alternates is not None:
+ return self._alternates
+ self._alternates = []
+ for path in self._read_alternate_paths():
+ self._alternates.append(DiskObjectStore(path))
+ return self._alternates
+
+ def _read_alternate_paths(self):
+ try:
+ f = GitFile(os.path.join(self.path, "info", "alternates"),
+ 'rb')
+ except (OSError, IOError), e:
+ if e.errno == errno.ENOENT:
+ return []
+ raise
+ ret = []
+ try:
+ for l in f.readlines():
+ l = l.rstrip("\n")
+ if l[0] == "#":
+ continue
+ if not os.path.isabs(l):
+ continue
+ ret.append(l)
+ return ret
+ finally:
+ f.close()
+
+ def add_alternate_path(self, path):
+ """Add an alternate path to this object store.
+ """
+ try:
+ os.mkdir(os.path.join(self.path, "info"))
+ except OSError, e:
+ if e.errno != errno.EEXIST:
+ raise
+ # FIXME: Locking
+ f = GitFile(os.path.join(self.path, "info/alternates"), 'wb')
+ try:
+ f.seek(0, os.SEEK_END)
+ f.write("%s\n" % path)
+ finally:
+ f.close()
+ self.alternates.append(DiskObjectStore(path))
def _load_packs(self):
pack_files = []
|
@@ -221,12 +221,23 @@ def setUp(self):
TestCase.setUp(self)
self.store_dir = tempfile.mkdtemp()
+ self.addCleanup(shutil.rmtree, self.store_dir)
self.store = DiskObjectStore.init(self.store_dir)
def tearDown(self):
TestCase.tearDown(self)
PackBasedObjectStoreTests.tearDown(self)
- shutil.rmtree(self.store_dir)
+
+ def test_alternates(self):
+ alternate_dir = tempfile.mkdtemp()
+ self.addCleanup(shutil.rmtree, alternate_dir)
+ alternate_store = DiskObjectStore(alternate_dir)
+ b2 = make_object(Blob, data="yummy data")
+ alternate_store.add_object(b2)
+ store = DiskObjectStore(self.store_dir)
+ self.assertRaises(KeyError, store.__getitem__, b2.id)
+ store.add_alternate_path(alternate_dir)
+ self.assertEquals(b2, store[b2.id])
def test_pack_dir(self):
o = DiskObjectStore(self.store_dir)
|
Loading...