diff options
Diffstat (limited to 'git/db/py/loose.py')
-rw-r--r-- | git/db/py/loose.py | 128 |
1 files changed, 63 insertions, 65 deletions
diff --git a/git/db/py/loose.py b/git/db/py/loose.py index 8267be98..40639e4e 100644 --- a/git/db/py/loose.py +++ b/git/db/py/loose.py @@ -3,53 +3,53 @@ # This module is part of GitDB and is released under # the New BSD License: http://www.opensource.org/licenses/bsd-license.php from base import ( - PureRootPathDB, - PureObjectDBR, - PureObjectDBW - ) + PureRootPathDB, + PureObjectDBR, + PureObjectDBW +) from git.exc import ( - InvalidDBRoot, + InvalidDBRoot, BadObject, AmbiguousObjectName - ) +) from git.stream import ( - DecompressMemMapReader, - FDCompressedSha1Writer, - FDStream, - Sha1Writer - ) + DecompressMemMapReader, + FDCompressedSha1Writer, + FDStream, + Sha1Writer +) from git.base import ( - OStream, - OInfo - ) + OStream, + OInfo +) from git.util import ( - file_contents_ro_filepath, - ENOENT, - hex_to_bin, - bin_to_hex, - exists, - chmod, - isdir, - isfile, - remove, - mkdir, - rename, - dirname, - basename, - join - ) - -from git.fun import ( + file_contents_ro_filepath, + ENOENT, + hex_to_bin, + bin_to_hex, + exists, + chmod, + isdir, + isfile, + remove, + mkdir, + rename, + dirname, + basename, + join +) + +from git.fun import ( chunk_size, - loose_object_header_info, + loose_object_header_info, write_object, stream_copy - ) +) import tempfile import mmap @@ -57,23 +57,23 @@ import sys import os -__all__ = ( 'PureLooseObjectODB', ) +__all__ = ('PureLooseObjectODB', ) class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): + """A database which operates on loose object files""" - + # CONFIGURATION # chunks in which data will be copied between streams stream_chunk_size = chunk_size - + # On windows we need to keep it writable, otherwise it cannot be removed # either new_objects_mode = 0444 if os.name == 'nt': new_objects_mode = 0644 - - + def __init__(self, root_path): super(PureLooseObjectODB, self).__init__(root_path) self._hexsha_to_file = dict() @@ -81,14 +81,14 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): # Depending on the root, this might work for some mounts, for others not, which # is why it is per instance self._fd_open_flags = getattr(os, 'O_NOATIME', 0) - - #{ Interface + + #{ Interface def object_path(self, hexsha): """ :return: path at which the object with the given hexsha would be stored, relative to the database root""" return join(hexsha[:2], hexsha[2:]) - + def readable_db_object_path(self, hexsha): """ :return: readable object path to the object identified by hexsha @@ -97,8 +97,8 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): return self._hexsha_to_file[hexsha] except KeyError: pass - # END ignore cache misses - + # END ignore cache misses + # try filesystem path = self.db_path(self.object_path(hexsha)) if exists(path): @@ -106,10 +106,9 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): return path # END handle cache raise BadObject(hexsha) - - + #} END interface - + def _map_loose_object(self, sha): """ :return: memory map of that file to allow random read access @@ -117,7 +116,7 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): db_path = self.db_path(self.object_path(bin_to_hex(sha))) try: return file_contents_ro_filepath(db_path, flags=self._fd_open_flags) - except OSError,e: + except OSError, e: if e.errno != ENOENT: # try again without noatime try: @@ -135,13 +134,13 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): finally: os.close(fd) # END assure file is closed - + def set_ostream(self, stream): """:raise TypeError: if the stream does not support the Sha1Writer interface""" if stream is not None and not isinstance(stream, Sha1Writer): raise TypeError("Output stream musst support the %s interface" % Sha1Writer.__name__) return super(PureLooseObjectODB, self).set_ostream(stream) - + def info(self, sha): m = self._map_loose_object(sha) try: @@ -150,12 +149,12 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): finally: m.close() # END assure release of system resources - + def stream(self, sha): m = self._map_loose_object(sha) - type, size, stream = DecompressMemMapReader.new(m, close_on_deletion = True) + type, size, stream = DecompressMemMapReader.new(m, close_on_deletion=True) return OStream(sha, type, size, stream) - + def has_object(self, sha): try: self.readable_db_object_path(bin_to_hex(sha)) @@ -163,7 +162,7 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): except BadObject: return False # END check existance - + def partial_to_complete_sha_hex(self, partial_hexsha): """:return: 20 byte binary sha1 string which matches the given name uniquely :param name: hexadecimal partial name @@ -180,7 +179,7 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): if candidate is None: raise BadObject(partial_hexsha) return candidate - + def store(self, istream): """note: The sha we produce will be hex by nature""" tmp_path = None @@ -188,14 +187,14 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): if writer is None: # open a tmp file to write the data to fd, tmp_path = tempfile.mkstemp(prefix='obj', dir=self._root_path) - + if istream.binsha is None: writer = FDCompressedSha1Writer(fd) else: writer = FDStream(fd) # END handle direct stream copies # END handle custom writer - + try: try: if istream.binsha is not None: @@ -205,7 +204,7 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): else: # write object with header, we have to make a new one write_object(istream.type, istream.size, istream.read, writer.write, - chunk_size=self.stream_chunk_size) + chunk_size=self.stream_chunk_size) # END handle direct stream copies finally: if tmp_path: @@ -216,14 +215,14 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): os.remove(tmp_path) raise # END assure tmpfile removal on error - + hexsha = None if istream.binsha: hexsha = istream.hexsha else: hexsha = writer.sha(as_hex=True) # END handle sha - + if tmp_path: obj_path = self.db_path(self.object_path(hexsha)) obj_dir = dirname(obj_path) @@ -235,29 +234,28 @@ class PureLooseObjectODB(PureRootPathDB, PureObjectDBR, PureObjectDBW): remove(obj_path) # END handle win322 rename(tmp_path, obj_path) - + # make sure its readable for all ! It started out as rw-- tmp file # but needs to be rwrr chmod(obj_path, self.new_objects_mode) # END handle dry_run - + istream.binsha = hex_to_bin(hexsha) return istream - + def sha_iter(self): # find all files which look like an object, extract sha from there for root, dirs, files in os.walk(self.root_path()): root_base = basename(root) if len(root_base) != 2: continue - + for f in files: if len(f) != 38: continue yield hex_to_bin(root_base + f) # END for each file # END for each walk iteration - + def size(self): return len(tuple(self.sha_iter())) - |