Skip to content

Commit 4bb5107

Browse files
committed
Initial version of the DulwichType inheritance. For now, it inherits everything from the existing implementation, but one by one things can be reimplmented to use dulwich.
It also shows that py 2.6 is quite plagued from its new feature, which is actually a bug, as objects inability to accept any args makes mixins hard to use ...
1 parent d5038eb commit 4bb5107

File tree

11 files changed

+133
-50
lines changed

11 files changed

+133
-50
lines changed

git/db/compat.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,10 @@
44
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
55
"""Module providing adaptors to maintain backwards compatability"""
66

7-
class RepoCompatibilityInterface(object):
7+
class RepoCompatibilityInterfaceNoBare(object):
88
"""Interface to install backwards compatability of the new complex repository
99
types with the previous, all in one, repository."""
1010

11-
@property
12-
def bare(self):
13-
return self.is_bare
14-
1511
def rev_parse(self, *args, **kwargs):
1612
return self.resolve_object(*args, **kwargs)
1713

@@ -28,4 +24,22 @@ def active_branch(self):
2824
return self.head.reference
2925

3026
def __repr__(self):
27+
"""Return the representation of the repository, the way it used to be"""
3128
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

git/db/dulwich/base.py

Lines changed: 0 additions & 6 deletions
This file was deleted.

git/db/dulwich/complex.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
20+
import os
21+
22+
23+
class DulwichGitODB(PureGitODB):
24+
"""A full fledged database to read and write object files from all kinds of sources."""
25+
26+
def __init__(self, objects_root):
27+
"""Initalize this instance"""
28+
PureGitODB.__init__(self, objects_root)
29+
self._dw_repo = DulwichRepo(self.working_dir)
30+
31+
def __getattr__(self, attr):
32+
try:
33+
# supply LazyMixin with this call first
34+
return super(DulwichGitODB, self).__getattr__(attr)
35+
except AttributeError:
36+
# now assume its on the dulwich repository ... for now
37+
return getattr(self._dw_repo, attr)
38+
#END handle attr
39+
40+
41+
class DulwichGitDB( PureRepositoryPathsMixin, PureConfigurationMixin,
42+
PureReferencesMixin, PureSubmoduleDB,
43+
PureIndexDB,
44+
PureTransportDB, # not fully implemented
45+
GitCommandMixin,
46+
CmdHighLevelRepository,
47+
DulwichGitODB): # must come last, as it doesn't pass on __init__ with super
48+
49+
50+
def __init__(self, root_path):
51+
"""Initialize ourselves on the .git directory, or the .git/objects directory."""
52+
PureRepositoryPathsMixin._initialize(self, root_path)
53+
super(DulwichGitDB, self).__init__(self.objects_dir)
54+
55+
56+
class DulwichCompatibilityGitDB(RepoCompatibilityInterfaceNoBare, DulwichGitDB):
57+
"""Basic dulwich compatibility database"""
58+
pass
59+

git/db/interface.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -561,16 +561,8 @@ def delete_tag(self, *tags):
561561
raise NotImplementedError()
562562

563563
#}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+
574566
class RepositoryPathsMixin(object):
575567
"""Represents basic functionality of a full git repository. This involves an
576568
optional working tree, a git directory with references and an object directory.

git/db/py/base.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ def __init__(self, root_path):
104104
super(PureRootPathDB, self).__init__(root_path)
105105

106106

107-
108107
#{ Interface
109108
def root_path(self):
110109
return self._root_path
@@ -233,7 +232,7 @@ def partial_to_complete_sha(self, partial_binsha, hex_len):
233232

234233
class PureRepositoryPathsMixin(RepositoryPathsMixin):
235234
# slots has no effect here, its just to keep track of used attrs
236-
__slots__ = ("_git_path", '_bare')
235+
__slots__ = ("_git_path", '_bare', '_working_tree_dir')
237236

238237
#{ Configuration
239238
repo_dir = '.git'
@@ -272,14 +271,16 @@ def _initialize(self, path):
272271
raise InvalidGitRepositoryError(epath)
273272
# END path not found
274273

275-
self._bare = self._git_path.endswith(self.repo_dir)
274+
self._bare = self._working_tree_dir is None
276275
if hasattr(self, 'config_reader'):
277276
try:
278277
self._bare = self.config_reader("repository").getboolean('core','bare')
279278
except Exception:
280279
# lets not assume the option exists, although it should
281280
pass
281+
#END handle exception
282282
#END check bare flag
283+
self._working_tree_dir = self._bare and None or self._working_tree_dir
283284

284285
#} end subclass interface
285286

@@ -313,7 +314,7 @@ def git_dir(self):
313314

314315
@property
315316
def working_tree_dir(self):
316-
if self.is_bare:
317+
if self._working_tree_dir is None:
317318
raise AssertionError("Repository at %s is bare and does not have a working tree directory" % self.git_dir)
318319
#END assertion
319320
return dirname(self.git_dir)
@@ -354,6 +355,10 @@ class PureConfigurationMixin(ConfigurationMixin):
354355
repo_config_file_name = "config"
355356
#} END
356357

358+
def __new__(cls, *args, **kwargs):
359+
"""This is just a stupid workaround for the evil py2.6 change which makes mixins quite impossible"""
360+
return super(PureConfigurationMixin, cls).__new__(cls, *args, **kwargs)
361+
357362
def __init__(self, *args, **kwargs):
358363
"""Verify prereqs"""
359364
try:
@@ -421,7 +426,11 @@ class PureAlternatesFileMixin(object):
421426
#} END configuration
422427

423428
def __init__(self, *args, **kwargs):
424-
super(PureAlternatesFileMixin, self).__init__(*args, **kwargs)
429+
try:
430+
super(PureAlternatesFileMixin, self).__init__(*args, **kwargs)
431+
except TypeError:
432+
pass
433+
#END handle py2.6 code breaking changes
425434
self._alternates_path() # throws on incompatible type
426435

427436
#{ Interface

git/db/py/complex.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,7 @@
2222

2323
from git.db.compat import RepoCompatibilityInterface
2424

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
3626
import os
3727

3828
__all__ = ('PureGitODB', 'PurePartialGitDB', 'PureCompatibilityGitDB')
@@ -106,7 +96,8 @@ def set_ostream(self, ostream):
10696
class PurePartialGitDB(PureGitODB,
10797
PureRepositoryPathsMixin, PureConfigurationMixin,
10898
PureReferencesMixin, PureSubmoduleDB,
109-
PureIndexDB, PureTransportDB
99+
PureIndexDB,
100+
PureTransportDB # not fully implemented
110101
# HighLevelRepository Currently not implemented !
111102
):
112103
"""Git like database with support for object lookup as well as reference resolution.
@@ -122,7 +113,6 @@ def __init__(self, root_path):
122113
super(PurePartialGitDB, self).__init__(self.objects_dir)
123114

124115

125-
126116
class PureCompatibilityGitDB(PurePartialGitDB, RepoCompatibilityInterface):
127117
"""Pure git database with a compatability layer required by 0.3x code"""
128118

git/db/py/resolve.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,3 @@ def create_tag(self, path, ref='HEAD', message=None, force=False, **kwargs):
361361
def delete_tag(self, *tags):
362362
return self.TagReferenceCls.delete(self, *tags)
363363

364-
365-
# compat
366-
branches = heads
367-
refs = references

git/test/db/base.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,8 +613,14 @@ def test_submodules(self):
613613
def test_submodule_update(self, rwrepo):
614614
# fails in bare mode
615615
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
616619
self.failUnlessRaises(InvalidGitRepositoryError, rwrepo.submodule_update)
617620
rwrepo._bare = False
621+
if rwrepo.bare:
622+
rwrepo.bare = False
623+
#END special repo handling
618624

619625
# test create submodule
620626
sm = rwrepo.submodules[0]

git/test/db/dulwich/lib.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
"""dulwich specific utilities, as well as all the default ones"""
22

3-
from git.test.lib import *
3+
from git.test.lib import (
4+
InheritedTestMethodsOverrideWrapperMetaClsAutoMixin,
5+
needs_module_or_skip
6+
)
7+
8+
__all__ = ['needs_dulwich_or_skip', 'DulwichRequiredMetaMixin']
49

510
#{ Decoorators
611

git/test/db/dulwich/test_base.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,31 @@
33
# This module is part of GitDB and is released under
44
# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
55
from lib import *
6+
from git.test.lib import TestBase, with_rw_repo
67
from git.test.db.base import RepoBase
7-
from git.db.complex import PureCompatibilityGitDB
8+
9+
810

911
try:
1012
import dulwich
1113
except ImportError:
1214
# om this case, all other dulwich tests will be skipped
13-
pass
15+
# Need to properly initialize the class though, otherwise it would fail
16+
from git.db.complex import PureCompatibilityGitDB as DulwichDB
17+
else:
18+
# now we know dulwich is available, to do futher imports
19+
from git.db.dulwich.complex import DulwichCompatibilityGitDB as DulwichDB
20+
21+
#END handle imports
1422

1523
class TestPyDBBase(RepoBase):
1624
__metaclass__ = DulwichRequiredMetaMixin
17-
RepoCls = PureCompatibilityGitDB
25+
RepoCls = DulwichDB
1826

1927
@needs_dulwich_or_skip
20-
def test_basics(self):
21-
import dulwich
22-
pass
28+
@with_rw_repo('HEAD', bare=False)
29+
def test_basics(self, rw_repo):
30+
db = DulwichDB(rw_repo.working_tree_dir)
31+
print db.git_dir
32+
2333

git/test/test_remote.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
SymbolicReference
2222
)
2323

24+
from nose import SkipTest
25+
2426
import tempfile
2527
import shutil
2628
import os
@@ -352,7 +354,13 @@ def _verify_push_and_pull(self,remote, rw_repo, remote_repo):
352354
# the same repository
353355
TagReference.delete(rw_repo, new_tag, other_tag)
354356
remote.push(":%s" % other_tag.path)
357+
358+
def test_todo(self):
359+
# If you see this, plesase remind yourself, that all this needs to be run
360+
# per repository type !
361+
raise SkipTest("todo")
355362

363+
356364
@with_rw_and_rw_remote_repo('0.1.6')
357365
def test_base(self, rw_repo, remote_repo):
358366
num_remotes = 0

0 commit comments

Comments
 (0)