summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2011-05-10 10:21:26 +0200
committerSebastian Thiel <byronimo@gmail.com>2011-05-10 10:21:26 +0200
commitcd26aaebbda94dc3740e41bbd3f91ba6b1a25c10 (patch)
tree7ea33a01a8a33b3cea92e0f6872bb1c7b5279a5e
parent7ae36c3e019a5cc16924d1b6007774bfb625036f (diff)
downloadgitpython-cd26aaebbda94dc3740e41bbd3f91ba6b1a25c10.tar.gz
Made repository paths methods a property to be compatible with the existing repo interface. Added submodule interface ... goal is to provide all of the extra repo functionality in custom interfaces
-rw-r--r--git/db/compat.py13
-rw-r--r--git/db/interface.py79
-rw-r--r--git/db/py/base.py67
-rw-r--r--git/db/py/complex.py5
-rw-r--r--git/db/py/submodule.py33
-rw-r--r--git/objects/submodule/__init__.py4
-rw-r--r--git/objects/submodule/base.py4
-rw-r--r--git/objects/submodule/root.py5
-rw-r--r--git/objects/submodule/util.py4
-rw-r--r--git/refs/log.py2
-rw-r--r--git/refs/symbolic.py18
-rw-r--r--git/repo/base.py39
-rw-r--r--git/test/test_base.py27
-rw-r--r--git/test/test_import.py14
14 files changed, 234 insertions, 80 deletions
diff --git a/git/db/compat.py b/git/db/compat.py
new file mode 100644
index 00000000..1c0ba6f5
--- /dev/null
+++ b/git/db/compat.py
@@ -0,0 +1,13 @@
+# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors
+#
+# This module is part of GitDB and is released under
+# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
+"""Module providing adaptors to maintain backwards compatability"""
+
+class RepoCompatInterface(object):
+ """Interface to install backwards compatability of the new complex repository
+ types with the previous, all in one, repository."""
+
+ @property
+ def bare(self):
+ return self.is_bare
diff --git a/git/db/interface.py b/git/db/interface.py
index b7c167c5..bdda70b3 100644
--- a/git/db/interface.py
+++ b/git/db/interface.py
@@ -6,7 +6,7 @@
__all__ = ( 'ObjectDBR', 'ObjectDBW', 'RootPathDB', 'CompoundDB', 'CachingDB',
'TransportDB', 'ConfigurationMixin', 'RepositoryPathsMixin',
- 'RefSpec', 'FetchInfo', 'PushInfo', 'ReferencesMixin')
+ 'RefSpec', 'FetchInfo', 'PushInfo', 'ReferencesMixin', 'SubmoduleDB')
class ObjectDBR(object):
@@ -151,7 +151,7 @@ class RootPathDB(object):
access."""
super(RootPathDB, self).__init__(root_path)
- #{ Interface
+ #{ Interface
def root_path(self):
""":return: path at which this db operates"""
raise NotImplementedError()
@@ -390,33 +390,60 @@ class RepositoryPathsMixin(object):
raise NotImplementedError()
#} end subclass interface
+ #{ Object Interface
+
+ def __eq__(self, rhs):
+ raise NotImplementedError()
+
+ def __ne__(self, rhs):
+ raise NotImplementedError()
+
+ def __hash__(self):
+ raise NotImplementedError()
+
+ def __repr__(self):
+ raise NotImplementedError()
+
+ #} END object interface
+
#{ Interface
+ @property
def is_bare(self):
""":return: True if this is a bare repository
:note: this value is cached upon initialization"""
raise NotImplementedError()
- def git_path(self):
+ @property
+ def git_dir(self):
""":return: path to directory containing this actual git repository (which
in turn provides access to objects and references"""
raise NotImplementedError()
- def working_tree_path(self):
+ @property
+ def working_tree_dir(self):
""":return: path to directory containing the working tree checkout of our
git repository.
:raise AssertionError: If this is a bare repository"""
raise NotImplementedError()
- def objects_path(self):
+ @property
+ def objects_dir(self):
""":return: path to the repository's objects directory"""
raise NotImplementedError()
+ @property
def working_dir(self):
""":return: working directory of the git process or related tools, being
- either the working_tree_path if available or the git_path"""
+ either the working_tree_dir if available or the git_path"""
raise NotImplementedError()
-
+
+ @property
+ def description(self):
+ """:return: description text associated with this repository or set the
+ description."""
+ raise NotImplementedError()
+
#} END interface
@@ -465,5 +492,43 @@ class ConfigurationMixin(object):
repository = configuration file for this repostory only"""
raise NotImplementedError()
+
#} END interface
+
+class SubmoduleDB(object):
+ """Interface providing access to git repository submodules.
+ The actual implementation is found in the Submodule object type, which is
+ currently only available in one implementation."""
+
+ @property
+ def submodules(self):
+ """
+ :return: git.IterableList(Submodule, ...) of direct submodules
+ available from the current head"""
+ raise NotImplementedError()
+
+ def submodule(self, name):
+ """ :return: Submodule with the given name
+ :raise ValueError: If no such submodule exists"""
+ raise NotImplementedError()
+
+ def create_submodule(self, *args, **kwargs):
+ """Create a new submodule
+
+ :note: See the documentation of Submodule.add for a description of the
+ applicable parameters
+ :return: created submodules"""
+ raise NotImplementedError()
+
+ def iter_submodules(self, *args, **kwargs):
+ """An iterator yielding Submodule instances, see Traversable interface
+ for a description of args and kwargs
+ :return: Iterator"""
+ raise NotImplementedError()
+
+ def submodule_update(self, *args, **kwargs):
+ """Update the submodules, keeping the repository consistent as it will
+ take the previous state into consideration. For more information, please
+ see the documentation of RootModule.update"""
+ raise NotImplementedError()
diff --git a/git/db/py/base.py b/git/db/py/base.py
index 5c470ba4..f45711d5 100644
--- a/git/db/py/base.py
+++ b/git/db/py/base.py
@@ -273,34 +273,70 @@ class PureRepositoryPathsMixin(RepositoryPathsMixin):
# lets not assume the option exists, although it should
pass
#END check bare flag
+
+ #} end subclass interface
+
+ #{ Object Interface
+
+ def __eq__(self, rhs):
+ if hasattr(rhs, 'git_dir'):
+ return self.git_dir == rhs.git_dir
+ return False
+
+ def __ne__(self, rhs):
+ return not self.__eq__(rhs)
+
+ def __hash__(self):
+ return hash(self.git_dir)
+ def __repr__(self):
+ return "%s(%r)" % (type(self).__name__, self.git_dir)
- #} end subclass interface
+ #} END object interface
#{ Interface
+ @property
def is_bare(self):
return self._bare
- def git_path(self):
+ @property
+ def git_dir(self):
return self._git_path
- def working_tree_path(self):
- if self.is_bare():
- raise AssertionError("Repository at %s is bare and does not have a working tree directory" % self.git_path())
+ @property
+ def working_tree_dir(self):
+ if self.is_bare:
+ raise AssertionError("Repository at %s is bare and does not have a working tree directory" % self.git_dir)
#END assertion
- return dirname(self.git_path())
-
- def objects_path(self):
- return join(self.git_path(), self.objs_dir)
-
+ return dirname(self.git_dir)
+
+ @property
+ def objects_dir(self):
+ return join(self.git_dir, self.objs_dir)
+
+ @property
def working_dir(self):
- if self.is_bare():
- return self.git_path()
+ if self.is_bare:
+ return self.git_dir
else:
- return self.working_tree_dir()
+ return self.working_tree_dir
#END handle bare state
+ def _mk_description():
+ def _get_description(self):
+ filename = join(self.git_dir, 'description')
+ return file(filename).read().rstrip()
+
+ def _set_description(self, descr):
+ filename = join(self.git_dir, 'description')
+ file(filename, 'w').write(descr+'\n')
+
+ return property(_get_description, _set_description, "Descriptive text for the content of the repository")
+
+ description = _mk_description()
+ del(_mk_description)
+
#} END interface
@@ -313,7 +349,7 @@ class PureConfigurationMixin(ConfigurationMixin):
def __init__(self, *args, **kwargs):
"""Verify prereqs"""
- assert hasattr(self, 'git_path')
+ assert hasattr(self, 'git_dir')
def _path_at_level(self, level ):
# we do not support an absolute path of the gitconfig on windows ,
@@ -327,7 +363,7 @@ class PureConfigurationMixin(ConfigurationMixin):
elif level == "global":
return normpath(expanduser("~/.%s" % self.system_config_file_name))
elif level == "repository":
- return join(self.git_path(), self.repo_config_file_name)
+ return join(self.git_dir, self.repo_config_file_name)
#END handle level
raise ValueError("Invalid configuration level: %r" % level)
@@ -346,5 +382,6 @@ class PureConfigurationMixin(ConfigurationMixin):
def config_writer(self, config_level="repository"):
return GitConfigParser(self._path_at_level(config_level), read_only=False)
+
#} END interface
diff --git a/git/db/py/complex.py b/git/db/py/complex.py
index 1f929e31..de68d4fd 100644
--- a/git/db/py/complex.py
+++ b/git/db/py/complex.py
@@ -15,6 +15,7 @@ from resolve import PureReferencesMixin
from loose import PureLooseObjectODB
from pack import PurePackedODB
from ref import PureReferenceDB
+from submodule import PureSubmoduleDB
from git.util import (
LazyMixin,
@@ -32,7 +33,7 @@ import os
__all__ = ('PureGitODB', 'PureGitDB')
-class PureGitODB(PureRootPathDB, PureObjectDBW, PureCompoundDB):
+class PureGitODB(PureRootPathDB, PureObjectDBW, PureCompoundDB, PureSubmoduleDB):
"""A git-style object-only database, which contains all objects in the 'objects'
subdirectory.
:note: The type needs to be initialized on the ./objects directory to function,
@@ -107,7 +108,7 @@ class PureGitDB(PureGitODB, PureRepositoryPathsMixin, PureConfigurationMixin, Pu
def __init__(self, root_path):
"""Initialize ourselves on the .git directory, or the .git/objects directory."""
PureRepositoryPathsMixin._initialize(self, root_path)
- super(PureGitDB, self).__init__(self.objects_path())
+ super(PureGitDB, self).__init__(self.objects_dir)
diff --git a/git/db/py/submodule.py b/git/db/py/submodule.py
new file mode 100644
index 00000000..735f90b1
--- /dev/null
+++ b/git/db/py/submodule.py
@@ -0,0 +1,33 @@
+# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors
+#
+# This module is part of GitDB and is released under
+# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
+from git.objects.submodule.base import Submodule
+from git.objects.submodule.root import RootModule
+from git.db.interface import SubmoduleDB
+
+__all__ = ["PureSubmoduleDB"]
+
+class PureSubmoduleDB(SubmoduleDB):
+ """Pure python implementation of submodule functionality"""
+
+ @property
+ def submodules(self):
+ return Submodule.list_items(self)
+
+ def submodule(self, name):
+ try:
+ return self.submodules[name]
+ except IndexError:
+ raise ValueError("Didn't find submodule named %r" % name)
+ # END exception handling
+
+ def create_submodule(self, *args, **kwargs):
+ return Submodule.add(self, *args, **kwargs)
+
+ def iter_submodules(self, *args, **kwargs):
+ return RootModule(self).traverse(*args, **kwargs)
+
+ def submodule_update(self, *args, **kwargs):
+ return RootModule(self).update(*args, **kwargs)
+
diff --git a/git/objects/submodule/__init__.py b/git/objects/submodule/__init__.py
index 82df59b0..c8bf2d49 100644
--- a/git/objects/submodule/__init__.py
+++ b/git/objects/submodule/__init__.py
@@ -1,2 +1,6 @@
+# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors
+#
+# This module is part of GitDB and is released under
+# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
# NOTE: Cannot import anything here as the top-level _init_ has to handle
# our dependencies
diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
index 62f4feee..a57111d3 100644
--- a/git/objects/submodule/base.py
+++ b/git/objects/submodule/base.py
@@ -1,3 +1,7 @@
+# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors
+#
+# This module is part of GitDB and is released under
+# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
from git.util import RepoAliasMixin
import util
from util import (
diff --git a/git/objects/submodule/root.py b/git/objects/submodule/root.py
index 132604f6..5e4cad2d 100644
--- a/git/objects/submodule/root.py
+++ b/git/objects/submodule/root.py
@@ -1,3 +1,7 @@
+# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors
+#
+# 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 Submodule, UpdateProgress
from util import (
find_first_remote_branch
@@ -24,6 +28,7 @@ BRANCHCHANGE = RootUpdateProgress.BRANCHCHANGE
URLCHANGE = RootUpdateProgress.URLCHANGE
PATHCHANGE = RootUpdateProgress.PATHCHANGE
+
class RootModule(Submodule):
"""A (virtual) Root of all submodules in the given repository. It can be used
to more easily traverse all submodules of the master repository"""
diff --git a/git/objects/submodule/util.py b/git/objects/submodule/util.py
index 9b32807a..2c5f6bc1 100644
--- a/git/objects/submodule/util.py
+++ b/git/objects/submodule/util.py
@@ -1,3 +1,7 @@
+# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors
+#
+# This module is part of GitDB and is released under
+# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
import git
from git.exc import InvalidGitRepositoryError
from git.config import GitConfigParser
diff --git a/git/refs/log.py b/git/refs/log.py
index 80102e7f..3b9d8514 100644
--- a/git/refs/log.py
+++ b/git/refs/log.py
@@ -151,7 +151,7 @@ class RefLog(list, Serializable):
instance would be found. The path is not guaranteed to point to a valid
file though.
:param ref: SymbolicReference instance"""
- return join(ref.repo.git_path(), "logs", to_native_path(ref.path))
+ return join(ref.repo.git_dir, "logs", to_native_path(ref.path))
@classmethod
def iter_entries(cls, stream):
diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py
index 1a0d3566..d670bd47 100644
--- a/git/refs/symbolic.py
+++ b/git/refs/symbolic.py
@@ -82,11 +82,11 @@ class SymbolicReference(object):
@property
def abspath(self):
- return join_path_native(self.repo.git_path(), self.path)
+ return join_path_native(self.repo.git_dir, self.path)
@classmethod
def _get_packed_refs_path(cls, repo):
- return join(repo.git_path(), 'packed-refs')
+ return join(repo.git_dir, 'packed-refs')
@classmethod
def _iter_packed_refs(cls, repo):
@@ -139,7 +139,7 @@ class SymbolicReference(object):
point to, or None"""
tokens = None
try:
- fp = open(join(repo.git_path(), ref_path), 'r')
+ fp = open(join(repo.git_dir, ref_path), 'r')
value = fp.read().rstrip()
fp.close()
tokens = value.split(" ")
@@ -416,7 +416,7 @@ class SymbolicReference(object):
or just "myreference", hence 'refs/' is implied.
Alternatively the symbolic reference to be deleted"""
full_ref_path = cls.to_full_path(path)
- abs_path = join(repo.git_path(), full_ref_path)
+ abs_path = join(repo.git_dir, full_ref_path)
if exists(abs_path):
os.remove(abs_path)
else:
@@ -469,7 +469,7 @@ class SymbolicReference(object):
corresponding object and a detached symbolic reference will be created
instead"""
full_ref_path = cls.to_full_path(path)
- abs_ref_path = join(repo.git_path(), full_ref_path)
+ abs_ref_path = join(repo.git_dir, full_ref_path)
# figure out target data
target = reference
@@ -550,8 +550,8 @@ class SymbolicReference(object):
if self.path == new_path:
return self
- new_abs_path = join(self.repo.git_path(), new_path)
- cur_abs_path = join(self.repo.git_path(), self.path)
+ new_abs_path = join(self.repo.git_dir, new_path)
+ cur_abs_path = join(self.repo.git_dir, self.path)
if isfile(new_abs_path):
if not force:
# if they point to the same file, its not an error
@@ -581,7 +581,7 @@ class SymbolicReference(object):
# walk loose refs
# Currently we do not follow links
- for root, dirs, files in os.walk(join_path_native(repo.git_path(), common_path)):
+ for root, dirs, files in os.walk(join_path_native(repo.git_dir, common_path)):
if 'refs/' not in root: # skip non-refs subfolders
refs_id = [ i for i,d in enumerate(dirs) if d == 'refs' ]
if refs_id:
@@ -590,7 +590,7 @@ class SymbolicReference(object):
for f in files:
abs_path = to_native_path_linux(join_path(root, f))
- rela_paths.add(abs_path.replace(to_native_path_linux(repo.git_path()) + '/', ""))
+ rela_paths.add(abs_path.replace(to_native_path_linux(repo.git_dir) + '/', ""))
# END for each file in root directory
# END for each directory to walk
diff --git a/git/repo/base.py b/git/repo/base.py
index 0b00cb9a..36c19ac8 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -219,45 +219,6 @@ class Repo(object):
:raise ValueError: if no remote with such a name exists"""
return Remote(self, name)
- #{ Submodules
-
- @property
- def submodules(self):
- """
- :return: git.IterableList(Submodule, ...) of direct submodules
- available from the current head"""
- return Submodule.list_items(self)
-
- def submodule(self, name):
- """ :return: Submodule with the given name
- :raise ValueError: If no such submodule exists"""
- try:
- return self.submodules[name]
- except IndexError:
- raise ValueError("Didn't find submodule named %r" % name)
- # END exception handling
-
- def create_submodule(self, *args, **kwargs):
- """Create a new submodule
-
- :note: See the documentation of Submodule.add for a description of the
- applicable parameters
- :return: created submodules"""
- return Submodule.add(self, *args, **kwargs)
-
- def iter_submodules(self, *args, **kwargs):
- """An iterator yielding Submodule instances, see Traversable interface
- for a description of args and kwargs
- :return: Iterator"""
- return RootModule(self).traverse(*args, **kwargs)
-
- def submodule_update(self, *args, **kwargs):
- """Update the submodules, keeping the repository consistent as it will
- take the previous state into consideration. For more information, please
- see the documentation of RootModule.update"""
- return RootModule(self).update(*args, **kwargs)
-
- #}END submodules
@property
def tags(self):
diff --git a/git/test/test_base.py b/git/test/test_base.py
index ca812ed4..7488ac6b 100644
--- a/git/test/test_base.py
+++ b/git/test/test_base.py
@@ -12,10 +12,15 @@ from lib import (
)
import git.objects.base as base
+from git.objects import (
+ Blob,
+ Tree,
+ Commit,
+ TagObject
+ )
import git.refs as refs
-import os
-from git import *
+
from itertools import chain
from git.objects.util import get_object_type_by_name
from git.util import hex_to_bin
@@ -23,14 +28,22 @@ import tempfile
##################
-from git import *
from git.util import (
NULL_BIN_SHA
)
-from git.typ import (
- str_blob_type
- )
+from git.typ import str_blob_type
+from git.base import (
+ OInfo,
+ OPackInfo,
+ ODeltaPackInfo,
+ OStream,
+ OPackStream,
+ ODeltaPackStream,
+ IStream,
+ )
+
+import os
class TestBase(TestBase):
@@ -94,7 +107,7 @@ class TestBase(TestBase):
assert base.Object in get_object_type_by_name(tname).mro()
# END for each known type
- assert_raises( ValueError, get_object_type_by_name, "doesntexist" )
+ self.failUnlessRaises(ValueError, get_object_type_by_name, "doesntexist")
def test_object_resolution(self):
# objects must be resolved to shas so they compare equal
diff --git a/git/test/test_import.py b/git/test/test_import.py
new file mode 100644
index 00000000..d97cee55
--- /dev/null
+++ b/git/test/test_import.py
@@ -0,0 +1,14 @@
+# Copyright (C) 2010, 2011 Sebastian Thiel (byronimo@gmail.com) and contributors
+#
+# This module is part of GitDB and is released under
+# the New BSD License: http://www.opensource.org/licenses/bsd-license.php
+"""This module's whole purpose is to verify the __all__ descriptions in the respective
+module, by importing using from x import *"""
+
+# perform the actual imports
+
+from nose import SkipTest
+
+class TestDummy(object):
+ def test_base(self):
+ raise SkipTest("todo")