2
0
Jelmer Vernooij 16 жил өмнө
parent
commit
dd0676d09a

+ 4 - 0
dulwich/__init__.py

@@ -18,6 +18,10 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301, USA.
 
+
+"""Python implementation of the Git file formats and protocols."""
+
+
 import client
 import protocol
 import repo

+ 1 - 1
dulwich/object_store.py

@@ -244,7 +244,7 @@ class ObjectStore(object):
         write_pack_data(f, objects, len(objects))
         commit()
 
-    def find_missing_objects(self, wants, graph_walker, progress):
+    def find_missing_objects(self, wants, graph_walker, progress=None):
         """Find the missing objects required for a set of revisions.
 
         :param wants: Iterable over SHAs of objects to fetch.

+ 66 - 13
dulwich/pack.py

@@ -472,7 +472,10 @@ class PackData(object):
         return self._num_objects
   
     def calculate_checksum(self):
-        """Calculate the checksum for this pack."""
+        """Calculate the checksum for this pack.
+
+        :return: 20-byte binary SHA1 digest
+        """
         map, map_offset = simple_mmap(self._file, 0, self._size - 20)
         try:
             return make_sha(map[map_offset:self._size-20]).digest()
@@ -585,12 +588,41 @@ class PackData(object):
         return ret
   
     def create_index_v1(self, filename, resolve_ext_ref=None, progress=None):
+        """Create a version 1 file for this data file.
+
+        :param filename: Index filename.
+        :param resolve_ext_ref: Function to use for resolving externally referenced
+            SHA1s (for thin packs)
+        :param progress: Progress report function
+        """
         entries = self.sorted_entries(resolve_ext_ref, progress=progress)
         write_pack_index_v1(filename, entries, self.calculate_checksum())
   
     def create_index_v2(self, filename, resolve_ext_ref=None, progress=None):
+        """Create a version 2 index file for this data file.
+
+        :param filename: Index filename.
+        :param resolve_ext_ref: Function to use for resolving externally referenced
+            SHA1s (for thin packs)
+        :param progress: Progress report function
+        """
         entries = self.sorted_entries(resolve_ext_ref, progress=progress)
         write_pack_index_v2(filename, entries, self.calculate_checksum())
+
+    def create_index(self, filename, resolve_ext_ref=None, progress=None, version=2):
+        """Create an  index file for this data file.
+
+        :param filename: Index filename.
+        :param resolve_ext_ref: Function to use for resolving externally referenced
+            SHA1s (for thin packs)
+        :param progress: Progress report function
+        """
+        if version == 1:
+            self.create_index_v1(filename, resolve_ext_ref, progress)
+        elif version == 2:
+            self.create_index_v2(filename, resolve_ext_ref, progress)
+        else:
+            raise ValueError("unknown index format %d" % version)
   
     def get_stored_checksum(self):
         return self._stored_checksum
@@ -619,6 +651,8 @@ class PackData(object):
 
 
 class SHA1Writer(object):
+    """Wrapper around a file-like object that remembers the SHA1 of 
+    the data written to it."""
     
     def __init__(self, f):
         self.f = f
@@ -681,6 +715,12 @@ def write_pack_object(f, type, object):
 
 
 def write_pack(filename, objects, num_objects):
+    """Write a new pack data file.
+
+    :param filename: Path to the new pack file (without .pack extension)
+    :param objects: Iterable over (object, path) tuples to write
+    :param num_objects: Number of objects to write
+    """
     f = open(filename + ".pack", 'w')
     try:
         entries, data_sum = write_pack_data(f, objects, num_objects)
@@ -762,7 +802,11 @@ def write_pack_index_v1(filename, entries, pack_checksum):
 
 
 def create_delta(base_buf, target_buf):
-    """Use python difflib to work out how to transform base_buf to target_buf"""
+    """Use python difflib to work out how to transform base_buf to target_buf.
+    
+    :param base_buf: Base buffer
+    :param target_buf: Target buffer
+    """
     assert isinstance(base_buf, str)
     assert isinstance(target_buf, str)
     out_buf = ""
@@ -914,6 +958,7 @@ def write_pack_index_v2(filename, entries, pack_checksum):
 
 
 class Pack(object):
+    """A Git pack object."""
 
     def __init__(self, basename):
         self._basename = basename
@@ -924,6 +969,7 @@ class Pack(object):
 
     @classmethod
     def from_objects(self, data, idx):
+        """Create a new pack object from pack data and index objects."""
         ret = Pack("")
         ret._data = data
         ret._idx = idx
@@ -931,14 +977,15 @@ class Pack(object):
 
     def name(self):
         """The SHA over the SHAs of the objects in this pack."""
-        return self.idx.objects_sha1()
+        return self.index.objects_sha1()
 
     @property
     def data(self):
+        """The pack data object being used."""
         if self._data is None:
             self._data = PackData(self._data_path)
-            assert len(self.idx) == len(self._data)
-            idx_stored_checksum = self.idx.get_pack_checksum()
+            assert len(self.index) == len(self._data)
+            idx_stored_checksum = self.index.get_pack_checksum()
             data_stored_checksum = self._data.get_stored_checksum()
             if idx_stored_checksum != data_stored_checksum:
                 raise ChecksumMismatch(sha_to_hex(idx_stored_checksum), 
@@ -946,7 +993,11 @@ class Pack(object):
         return self._data
 
     @property
-    def idx(self):
+    def index(self):
+        """The index being used.
+
+        :note: This may be an in-memory index
+        """
         if self._idx is None:
             self._idx = load_pack_index(self._idx_path)
         return self._idx
@@ -954,24 +1005,25 @@ class Pack(object):
     def close(self):
         if self._data is not None:
             self._data.close()
-        self.idx.close()
+        self.index.close()
 
     def __eq__(self, other):
-        return type(self) == type(other) and self.idx == other.idx
+        return type(self) == type(other) and self.index == other.index
 
     def __len__(self):
         """Number of entries in this pack."""
-        return len(self.idx)
+        return len(self.index)
 
     def __repr__(self):
         return "%s(%r)" % (self.__class__.__name__, self._basename)
 
     def __iter__(self):
         """Iterate over all the sha1s of the objects in this pack."""
-        return iter(self.idx)
+        return iter(self.index)
 
     def check(self):
-        if not self.idx.check():
+        """Check the integrity of this pack."""
+        if not self.index.check():
             return False
         if not self.data.check():
             return False
@@ -983,13 +1035,13 @@ class Pack(object):
     def __contains__(self, sha1):
         """Check whether this pack contains a particular SHA1."""
         try:
-            self.idx.object_index(sha1)
+            self.index.object_index(sha1)
             return True
         except KeyError:
             return False
 
     def get_raw(self, sha1, resolve_ref=None):
-        offset = self.idx.object_index(sha1)
+        offset = self.index.object_index(sha1)
         obj_type, obj = self.data.get_object_at(offset)
         if type(offset) is long:
           offset = int(offset)
@@ -1003,6 +1055,7 @@ class Pack(object):
         return ShaFile.from_raw_string(type, uncomp)
 
     def iterobjects(self, get_raw=None):
+        """Iterate over the objects in this pack."""
         if get_raw is None:
             get_raw = self.get_raw
         for offset, type, obj, crc32 in self.data.iterobjects():

+ 23 - 0
dulwich/repo.py

@@ -18,6 +18,8 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301, USA.
 
+"""Repository access."""
+
 import os
 import stat
 
@@ -111,6 +113,7 @@ class Repo(object):
         return self._controldir
 
     def index_path(self):
+        """Return path to the index file."""
         return os.path.join(self.controldir(), INDEX_FILENAME)
 
     def open_index(self):
@@ -154,6 +157,7 @@ class Repo(object):
             self.find_missing_objects(determine_wants, graph_walker, progress))
 
     def object_dir(self):
+        """Return path of the object directory."""
         return os.path.join(self.controldir(), OBJECTDIR)
 
     @property
@@ -190,6 +194,7 @@ class Repo(object):
             return packed_refs[name]
 
     def get_refs(self):
+        """Get dictionary with all refs."""
         ret = {}
         if self.head():
             ret['HEAD'] = self.head()
@@ -202,6 +207,13 @@ class Repo(object):
         return ret
 
     def get_packed_refs(self):
+        """Get contents of the packed-refs file.
+
+        :return: Dictionary mapping ref names to SHA1s
+
+        :note: Will return an empty dictionary when no packed-refs file is 
+            present.
+        """
         path = os.path.join(self.controldir(), 'packed-refs')
         if not os.path.exists(path):
             return {}
@@ -215,6 +227,11 @@ class Repo(object):
             f.close()
 
     def set_ref(self, name, value):
+        """Set a new ref.
+
+        :param name: Name of the ref
+        :param value: SHA1 to point at
+        """
         file = os.path.join(self.controldir(), name)
         dirpath = os.path.dirname(file)
         if not os.path.exists(dirpath):
@@ -226,6 +243,10 @@ class Repo(object):
             f.close()
 
     def remove_ref(self, name):
+        """Remove a ref.
+
+        :param name: Name of the ref
+        """
         file = os.path.join(self.controldir(), name)
         if os.path.exists(file):
             os.remove(file)
@@ -242,6 +263,7 @@ class Repo(object):
         return ret
 
     def heads(self):
+        """Return dictionary with heads."""
         ret = {}
         for root, dirs, files in os.walk(os.path.join(self.controldir(), REFSDIR, 'heads')):
             for name in files:
@@ -249,6 +271,7 @@ class Repo(object):
         return ret
 
     def head(self):
+        """Return the SHA1 pointed at by HEAD."""
         return self.ref('HEAD')
 
     def _get_object(self, sha, cls):