]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/git.py
Add bup get; see the documentation for further information
[bup.git] / lib / bup / git.py
index db704485961cd38961d638a6506a23ca14482461..73dce1914571adbe0be965c89c8ae4278329b4f4 100644 (file)
@@ -10,6 +10,7 @@ from itertools import islice
 from numbers import Integral
 
 from bup import _helpers, compat, hashsplit, path, midx, bloom, xstat
+from bup.compat import range
 from bup.helpers import (Sha1, add_error, chunkyreader, debug1, debug2,
                          fdatasync,
                          hostname, localtime, log, merge_iter,
@@ -111,13 +112,14 @@ def parse_commit(content):
                       message=matches['message'])
 
 
-def get_commit_items(id, cp):
-    commit_it = cp.get(id)
-    _, typ, _ = next(commit_it)
-    assert(typ == 'commit')
-    commit_content = ''.join(commit_it)
-    return parse_commit(commit_content)
+def get_cat_data(cat_iterator, expected_type):
+    _, kind, _ = next(cat_iterator)
+    if kind != expected_type:
+        raise Exception('expected %r, saw %r' % (expected_type, kind))
+    return ''.join(cat_iterator)
 
+def get_commit_items(id, cp):
+    return parse_commit(get_cat_data(cp.get(id), 'commit'))
 
 def _local_git_date_str(epoch_sec):
     return '%d %s' % (epoch_sec, utc_offset_str(epoch_sec))
@@ -395,7 +397,7 @@ class PackIdxV1(PackIdx):
         return str(self.shatable[idx*24+4 : idx*24+24])
 
     def __iter__(self):
-        for i in xrange(self.fanout[255]):
+        for i in range(self.fanout[255]):
             yield buffer(self.map, 256*4 + 24*i + 4, 20)
 
 
@@ -430,7 +432,7 @@ class PackIdxV2(PackIdx):
         return str(self.shatable[idx*20:(idx+1)*20])
 
     def __iter__(self):
-        for i in xrange(self.fanout[255]):
+        for i in range(self.fanout[255]):
             yield buffer(self.map, 8 + 256*4 + 20*i, 20)
 
 
@@ -637,6 +639,12 @@ class PackWriter:
     def __del__(self):
         self.close()
 
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        self.close()
+
     def _open(self):
         if not self.file:
             objdir = dir = os.path.join(self.repo_dir, 'objects')
@@ -1200,7 +1208,7 @@ class CatPipe:
             return
         info = hdr.split(' ')
         if len(info) != 3 or len(info[0]) != 40:
-            raise GitError('expected object (id, type, size), got %r' % spl)
+            raise GitError('expected object (id, type, size), got %r' % info)
         oidx, typ, size = info
         size = int(size)
         it = _AbortableIter(chunkyreader(self.p.stdout, size),
@@ -1295,14 +1303,13 @@ WalkItem = namedtuple('WalkItem', ['oid', 'type', 'mode',
 #   ...
 
 
-def walk_object(cat_pipe, oidx,
-                stop_at=None,
-                include_data=None):
-    """Yield everything reachable from oidx via cat_pipe as a WalkItem,
-    stopping whenever stop_at(oidx) returns true.  Throw MissingObject
-    if a hash encountered is missing from the repository, and don't
-    read or return blob content in the data field unless include_data
-    is set.
+def walk_object(get_ref, oidx, stop_at=None, include_data=None):
+    """Yield everything reachable from oidx via get_ref (which must behave
+    like CatPipe get) as a WalkItem, stopping whenever stop_at(oidx)
+    returns true.  Throw MissingObject if a hash encountered is
+    missing from the repository, and don't read or return blob content
+    in the data field unless include_data is set.
+
     """
     # Maintain the pending stack on the heap to avoid stack overflow
     pending = [(oidx, [], [], None)]
@@ -1322,7 +1329,7 @@ def walk_object(cat_pipe, oidx,
                            data=None)
             continue
 
-        item_it = cat_pipe.get(oidx)
+        item_it = get_ref(oidx)
         get_oidx, typ, _ = next(item_it)
         if not get_oidx:
             raise MissingObject(oidx.decode('hex'))