| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,3 +6,4 @@ | |||
| 6 | 6 | /dist | |
| 7 | 7 | /doc/_build | |
| 8 | 8 | nbproject | |
| 9 | + .nosebazinga | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,14 +4,10 @@ | |||
| 4 | 4 | # the New BSD License: http://www.opensource.org/licenses/bsd-license.php | |
| 5 | 5 | """Module providing adaptors to maintain backwards compatability""" | |
| 6 | 6 | ||
| 7 | - class RepoCompatibilityInterface(object): | ||
| 7 | + class RepoCompatibilityInterfaceNoBare(object): | ||
| 8 | 8 | """Interface to install backwards compatability of the new complex repository | |
| 9 | 9 | types with the previous, all in one, repository.""" | |
| 10 | 10 | ||
| 11 | - @property | ||
| 12 | - def bare(self): | ||
| 13 | - return self.is_bare | ||
| 14 | - | ||
| 15 | 11 | def rev_parse(self, *args, **kwargs): | |
| 16 | 12 | return self.resolve_object(*args, **kwargs) | |
| 17 | 13 | ||
@@ -28,4 +24,22 @@ def active_branch(self): | |||
| 28 | 24 | return self.head.reference | |
| 29 | 25 | ||
| 30 | 26 | def __repr__(self): | |
| 27 | + """Return the representation of the repository, the way it used to be""" | ||
| 31 | 28 | return '<git.Repo "%s">' % self.git_dir | |
| 29 | + | ||
| 30 | + @property | ||
| 31 | + def branches(self): | ||
| 32 | + return self.heads | ||
| 33 | + | ||
| 34 | + | ||
| 35 | + class RepoCompatibilityInterface(RepoCompatibilityInterfaceNoBare): | ||
| 36 | + """Interface to install backwards compatability of the new complex repository | ||
| 37 | + types with the previous, all in one, repository.""" | ||
| 38 | + | ||
| 39 | + @property | ||
| 40 | + def bare(self): | ||
| 41 | + return self.is_bare | ||
| 42 | + | ||
| 43 | + @property | ||
| 44 | + def refs(self): | ||
| 45 | + return self.references | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,13 @@ | |||
| 1 | + """Dulwich module initialization""" | ||
| 2 | + | ||
| 3 | + def init_dulwich(): | ||
| 4 | + """:raise ImportError: if dulwich is not present""" | ||
| 5 | + try: | ||
| 6 | + import dulwich | ||
| 7 | + except ImportError: | ||
| 8 | + raise ImportError("Could not find 'dulwich' in the PYTHONPATH - dulwich functionality is not available") | ||
| 9 | + #END handle dulwich import | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + init_dulwich() | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,90 @@ | |||
| 1 | + | ||
| 2 | + __all__ = ['DulwichGitODB', 'DulwichGitDB', 'DulwichCompatibilityGitDB'] | ||
| 3 | + | ||
| 4 | + from git.db.py.complex import PureGitODB | ||
| 5 | + from git.db.py.base import ( | ||
| 6 | + PureRepositoryPathsMixin, | ||
| 7 | + PureConfigurationMixin, | ||
| 8 | + PureIndexDB, | ||
| 9 | + ) | ||
| 10 | + from git.db.py.resolve import PureReferencesMixin | ||
| 11 | + from git.db.py.transport import PureTransportDB | ||
| 12 | + from git.db.py.submodule import PureSubmoduleDB | ||
| 13 | + | ||
| 14 | + from git.db.cmd.complex import CmdHighLevelRepository, GitCommandMixin | ||
| 15 | + from git.db.compat import RepoCompatibilityInterfaceNoBare | ||
| 16 | + | ||
| 17 | + #from git.db.interface import ObjectDBW, ObjectDBR | ||
| 18 | + from dulwich.repo import Repo as DulwichRepo | ||
| 19 | + from dulwich.objects import ShaFile | ||
| 20 | + | ||
| 21 | + from git.base import OInfo, OStream | ||
| 22 | + from git.fun import type_id_to_type_map, type_to_type_id_map | ||
| 23 | + | ||
| 24 | + from cStringIO import StringIO | ||
| 25 | + import os | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + class DulwichGitODB(PureGitODB): | ||
| 29 | + """A full fledged database to read and write object files from all kinds of sources.""" | ||
| 30 | + | ||
| 31 | + def __init__(self, objects_root): | ||
| 32 | + """Initalize this instance""" | ||
| 33 | + PureGitODB.__init__(self, objects_root) | ||
| 34 | + if hasattr(self, 'working_dir'): | ||
| 35 | + wd = self.working_dir | ||
| 36 | + else: | ||
| 37 | + wd = os.path.dirname(os.path.dirname(objects_root)) | ||
| 38 | + #END try to figure out good entry for dulwich, which doesn't do an extensive search | ||
| 39 | + self._dw_repo = DulwichRepo(wd) | ||
| 40 | + | ||
| 41 | + def __getattr__(self, attr): | ||
| 42 | + try: | ||
| 43 | + # supply LazyMixin with this call first | ||
| 44 | + return super(DulwichGitODB, self).__getattr__(attr) | ||
| 45 | + except AttributeError: | ||
| 46 | + # now assume its on the dulwich repository ... for now | ||
| 47 | + return getattr(self._dw_repo, attr) | ||
| 48 | + #END handle attr | ||
| 49 | + | ||
| 50 | + #{ Object DBR | ||
| 51 | + | ||
| 52 | + def info(self, binsha): | ||
| 53 | + type_id, uncomp_data = self._dw_repo.object_store.get_raw(binsha) | ||
| 54 | + return OInfo(binsha, type_id_to_type_map[type_id], len(uncomp_data)) | ||
| 55 | + | ||
| 56 | + def stream(self, binsha): | ||
| 57 | + type_id, uncomp_data = self._dw_repo.object_store.get_raw(binsha) | ||
| 58 | + return OStream(binsha, type_id_to_type_map[type_id], len(uncomp_data), StringIO(uncomp_data)) | ||
| 59 | + | ||
| 60 | + #}END object dbr | ||
| 61 | + | ||
| 62 | + #{ Object DBW | ||
| 63 | + | ||
| 64 | + def store(self, istream): | ||
| 65 | + obj = ShaFile.from_raw_string(type_to_type_id_map[istream.type], istream.read()) | ||
| 66 | + self._dw_repo.object_store.add_object(obj) | ||
| 67 | + istream.binsha = obj.sha().digest() | ||
| 68 | + return istream | ||
| 69 | + | ||
| 70 | + #}END object dbw | ||
| 71 | + | ||
| 72 | + class DulwichGitDB( PureRepositoryPathsMixin, PureConfigurationMixin, | ||
| 73 | + PureReferencesMixin, PureSubmoduleDB, | ||
| 74 | + PureIndexDB, | ||
| 75 | + PureTransportDB, # not fully implemented | ||
| 76 | + GitCommandMixin, | ||
| 77 | + CmdHighLevelRepository, | ||
| 78 | + DulwichGitODB): # must come last, as it doesn't pass on __init__ with super | ||
| 79 | + | ||
| 80 | + | ||
| 81 | + def __init__(self, root_path): | ||
| 82 | + """Initialize ourselves on the .git directory, or the .git/objects directory.""" | ||
| 83 | + PureRepositoryPathsMixin._initialize(self, root_path) | ||
| 84 | + super(DulwichGitDB, self).__init__(self.objects_dir) | ||
| 85 | + | ||
| 86 | + | ||
| 87 | + class DulwichCompatibilityGitDB(RepoCompatibilityInterfaceNoBare, DulwichGitDB): | ||
| 88 | + """Basic dulwich compatibility database""" | ||
| 89 | + pass | ||
| 90 | + | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -561,16 +561,8 @@ def delete_tag(self, *tags): | |||
| 561 | 561 | raise NotImplementedError() | |
| 562 | 562 | ||
| 563 | 563 | #}END edit methods | |
| 564 | - | ||
| 565 | - #{ Backward Compatability | ||
| 566 | - # These aliases need to be provided by the implementing interface as well | ||
| 567 | - refs = references | ||
| 568 | - branches = heads | ||
| 569 | - #} END backward compatability | ||
| 570 | - | ||
| 571 | - | ||
| 572 | - | ||
| 573 | - | ||
| 564 | + | ||
| 565 | + | ||
| 574 | 566 | class RepositoryPathsMixin(object): | |
| 575 | 567 | """Represents basic functionality of a full git repository. This involves an | |
| 576 | 568 | optional working tree, a git directory with references and an object directory. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -104,7 +104,6 @@ def __init__(self, root_path): | |||
| 104 | 104 | super(PureRootPathDB, self).__init__(root_path) | |
| 105 | 105 | ||
| 106 | 106 | ||
| 107 | - | ||
| 108 | 107 | #{ Interface | |
| 109 | 108 | def root_path(self): | |
| 110 | 109 | return self._root_path | |
@@ -132,44 +131,33 @@ class PureCompoundDB(CompoundDB, PureObjectDBR, LazyMixin, CachingDB): | |||
| 132 | 131 | def _set_cache_(self, attr): | |
| 133 | 132 | if attr == '_dbs': | |
| 134 | 133 | self._dbs = list() | |
| 135 | - elif attr == '_obj_cache': | ||
| 136 | - self._obj_cache = dict() | ||
| 137 | 134 | else: | |
| 138 | 135 | super(PureCompoundDB, self)._set_cache_(attr) | |
| 139 | 136 | ||
| 140 | - def _db_query(self, sha): | ||
| 141 | - """:return: database containing the given 20 byte sha | ||
| 142 | - :raise BadObject:""" | ||
| 143 | - # most databases use binary representations, prevent converting | ||
| 144 | - # it everytime a database is being queried | ||
| 145 | - try: | ||
| 146 | - return self._obj_cache[sha] | ||
| 147 | - except KeyError: | ||
| 148 | - pass | ||
| 149 | - # END first level cache | ||
| 150 | - | ||
| 151 | - for db in self._dbs: | ||
| 152 | - if db.has_object(sha): | ||
| 153 | - self._obj_cache[sha] = db | ||
| 154 | - return db | ||
| 155 | - # END for each database | ||
| 156 | - raise BadObject(sha) | ||
| 157 | - | ||
| 158 | 137 | #{ PureObjectDBR interface | |
| 159 | 138 | ||
| 160 | 139 | def has_object(self, sha): | |
| 161 | - try: | ||
| 162 | - self._db_query(sha) | ||
| 163 | - return True | ||
| 164 | - except BadObject: | ||
| 165 | - return False | ||
| 166 | - # END handle exceptions | ||
| 140 | + for db in self._dbs: | ||
| 141 | + if db.has_object(sha): | ||
| 142 | + return True | ||
| 143 | + #END for each db | ||
| 144 | + return False | ||
| 167 | 145 | ||
| 168 | 146 | def info(self, sha): | |
| 169 | - return self._db_query(sha).info(sha) | ||
| 147 | + for db in self._dbs: | ||
| 148 | + try: | ||
| 149 | + return db.info(sha) | ||
| 150 | + except BadObject: | ||
| 151 | + pass | ||
| 152 | + #END for each db | ||
| 170 | 153 | ||
| 171 | 154 | def stream(self, sha): | |
| 172 | - return self._db_query(sha).stream(sha) | ||
| 155 | + for db in self._dbs: | ||
| 156 | + try: | ||
| 157 | + return db.stream(sha) | ||
| 158 | + except BadObject: | ||
| 159 | + pass | ||
| 160 | + #END for each db | ||
| 173 | 161 | ||
| 174 | 162 | def size(self): | |
| 175 | 163 | return reduce(lambda x,y: x+y, (db.size() for db in self._dbs), 0) | |
@@ -186,7 +174,6 @@ def databases(self): | |||
| 186 | 174 | ||
| 187 | 175 | def update_cache(self, force=False): | |
| 188 | 176 | # something might have changed, clear everything | |
| 189 | - self._obj_cache.clear() | ||
| 190 | 177 | stat = False | |
| 191 | 178 | for db in self._dbs: | |
| 192 | 179 | if isinstance(db, CachingDB): | |
@@ -233,7 +220,7 @@ def partial_to_complete_sha(self, partial_binsha, hex_len): | |||
| 233 | 220 | ||
| 234 | 221 | class PureRepositoryPathsMixin(RepositoryPathsMixin): | |
| 235 | 222 | # slots has no effect here, its just to keep track of used attrs | |
| 236 | - __slots__ = ("_git_path", '_bare') | ||
| 223 | + __slots__ = ("_git_path", '_bare', '_working_tree_dir') | ||
| 237 | 224 | ||
| 238 | 225 | #{ Configuration | |
| 239 | 226 | repo_dir = '.git' | |
@@ -272,14 +259,16 @@ def _initialize(self, path): | |||
| 272 | 259 | raise InvalidGitRepositoryError(epath) | |
| 273 | 260 | # END path not found | |
| 274 | 261 | ||
| 275 | - self._bare = self._git_path.endswith(self.repo_dir) | ||
| 262 | + self._bare = self._working_tree_dir is None | ||
| 276 | 263 | if hasattr(self, 'config_reader'): | |
| 277 | 264 | try: | |
| 278 | 265 | self._bare = self.config_reader("repository").getboolean('core','bare') | |
| 279 | 266 | except Exception: | |
| 280 | 267 | # lets not assume the option exists, although it should | |
| 281 | 268 | pass | |
| 269 | + #END handle exception | ||
| 282 | 270 | #END check bare flag | |
| 271 | + self._working_tree_dir = self._bare and None or self._working_tree_dir | ||
| 283 | 272 | ||
| 284 | 273 | #} end subclass interface | |
| 285 | 274 | ||
@@ -313,7 +302,7 @@ def git_dir(self): | |||
| 313 | 302 | ||
| 314 | 303 | @property | |
| 315 | 304 | def working_tree_dir(self): | |
| 316 | - if self.is_bare: | ||
| 305 | + if self._working_tree_dir is None: | ||
| 317 | 306 | raise AssertionError("Repository at %s is bare and does not have a working tree directory" % self.git_dir) | |
| 318 | 307 | #END assertion | |
| 319 | 308 | return dirname(self.git_dir) | |
@@ -354,6 +343,10 @@ class PureConfigurationMixin(ConfigurationMixin): | |||
| 354 | 343 | repo_config_file_name = "config" | |
| 355 | 344 | #} END | |
| 356 | 345 | ||
| 346 | + def __new__(cls, *args, **kwargs): | ||
| 347 | + """This is just a stupid workaround for the evil py2.6 change which makes mixins quite impossible""" | ||
| 348 | + return super(PureConfigurationMixin, cls).__new__(cls, *args, **kwargs) | ||
| 349 | + | ||
| 357 | 350 | def __init__(self, *args, **kwargs): | |
| 358 | 351 | """Verify prereqs""" | |
| 359 | 352 | try: | |
@@ -421,7 +414,11 @@ class PureAlternatesFileMixin(object): | |||
| 421 | 414 | #} END configuration | |
| 422 | 415 | ||
| 423 | 416 | def __init__(self, *args, **kwargs): | |
| 424 | - super(PureAlternatesFileMixin, self).__init__(*args, **kwargs) | ||
| 417 | + try: | ||
| 418 | + super(PureAlternatesFileMixin, self).__init__(*args, **kwargs) | ||
| 419 | + except TypeError: | ||
| 420 | + pass | ||
| 421 | + #END handle py2.6 code breaking changes | ||
| 425 | 422 | self._alternates_path() # throws on incompatible type | |
| 426 | 423 | ||
| 427 | 424 | #{ Interface | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,17 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | 23 | from git.db.compat import RepoCompatibilityInterface | |
| 24 | 24 | ||
| 25 | - from git.util import ( | ||
| 26 | - LazyMixin, | ||
| 27 | - normpath, | ||
| 28 | - join, | ||
| 29 | - dirname | ||
| 30 | - ) | ||
| 31 | - from git.exc import ( | ||
| 32 | - InvalidDBRoot, | ||
| 33 | - BadObject, | ||
| 34 | - AmbiguousObjectName | ||
| 35 | - ) | ||
| 25 | + from git.exc import InvalidDBRoot | ||
| 36 | 26 | import os | |
| 37 | 27 | ||
| 38 | 28 | __all__ = ('PureGitODB', 'PurePartialGitDB', 'PureCompatibilityGitDB') | |
@@ -106,7 +96,8 @@ def set_ostream(self, ostream): | |||
| 106 | 96 | class PurePartialGitDB(PureGitODB, | |
| 107 | 97 | PureRepositoryPathsMixin, PureConfigurationMixin, | |
| 108 | 98 | PureReferencesMixin, PureSubmoduleDB, | |
| 109 | - PureIndexDB, PureTransportDB | ||
| 99 | + PureIndexDB, | ||
| 100 | + PureTransportDB # not fully implemented | ||
| 110 | 101 | # HighLevelRepository Currently not implemented ! | |
| 111 | 102 | ): | |
| 112 | 103 | """Git like database with support for object lookup as well as reference resolution. | |
@@ -122,7 +113,6 @@ def __init__(self, root_path): | |||
| 122 | 113 | super(PurePartialGitDB, self).__init__(self.objects_dir) | |
| 123 | 114 | ||
| 124 | 115 | ||
| 125 | - | ||
| 126 | 116 | class PureCompatibilityGitDB(PurePartialGitDB, RepoCompatibilityInterface): | |
| 127 | 117 | """Pure git database with a compatability layer required by 0.3x code""" | |
| 128 | 118 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -361,7 +361,3 @@ def create_tag(self, path, ref='HEAD', message=None, force=False, **kwargs): | |||
| 361 | 361 | def delete_tag(self, *tags): | |
| 362 | 362 | return self.TagReferenceCls.delete(self, *tags) | |
| 363 | 363 | ||
| 364 | - | ||
| 365 | - # compat | ||
| 366 | - branches = heads | ||
| 367 | - refs = references | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -601,20 +601,26 @@ def test_rev_parse(self): | |||
| 601 | 601 | self.failUnlessRaises(NotImplementedError, rev_parse, "@{1 week ago}") | |
| 602 | 602 | ||
| 603 | 603 | def test_submodules(self): | |
| 604 | - assert len(self.rorepo.submodules) == 1 # non-recursive | ||
| 604 | + assert len(self.rorepo.submodules) == 2 # non-recursive | ||
| 605 | 605 | # in previous configurations, we had recursive repositories so this would compare to 2 | |
| 606 | - # now there is only one left, as gitdb was merged | ||
| 607 | - assert len(list(self.rorepo.iter_submodules())) == 1 | ||
| 606 | + # now there is only one left, as gitdb was merged, but we have smmap instead | ||
| 607 | + assert len(list(self.rorepo.iter_submodules())) == 2 | ||
| 608 | 608 | ||
| 609 | - assert isinstance(self.rorepo.submodule("git/ext/async"), Submodule) | ||
| 609 | + assert isinstance(self.rorepo.submodule("async"), Submodule) | ||
| 610 | 610 | self.failUnlessRaises(ValueError, self.rorepo.submodule, "doesn't exist") | |
| 611 | 611 | ||
| 612 | 612 | @with_rw_repo('HEAD', bare=False) | |
| 613 | 613 | def test_submodule_update(self, rwrepo): | |
| 614 | 614 | # fails in bare mode | |
| 615 | 615 | rwrepo._bare = True | |
| 616 | + # special handling: there are repo implementations which have a bare attribute. IN that case, set it directly | ||
| 617 | + if not rwrepo.bare: | ||
| 618 | + rwrepo.bare = True | ||
| 616 | 619 | self.failUnlessRaises(InvalidGitRepositoryError, rwrepo.submodule_update) | |
| 617 | 620 | rwrepo._bare = False | |
| 621 | + if rwrepo.bare: | ||
| 622 | + rwrepo.bare = False | ||
| 623 | + #END special repo handling | ||
| 618 | 624 | ||
| 619 | 625 | # test create submodule | |
| 620 | 626 | sm = rwrepo.submodules[0] | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,4 @@ | |||
| 1 | + # Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors | ||
| 2 | + # | ||
| 3 | + # This module is part of GitDB and is released under | ||
| 4 | + # the New BSD License: http://www.opensource.org/licenses/bsd-license.php | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments