summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/git/objects/submodule.py40
-rw-r--r--test/git/test_submodule.py24
2 files changed, 53 insertions, 11 deletions
diff --git a/lib/git/objects/submodule.py b/lib/git/objects/submodule.py
index 93d47999..44dc9b02 100644
--- a/lib/git/objects/submodule.py
+++ b/lib/git/objects/submodule.py
@@ -1,11 +1,11 @@
import base
from util import Traversable
from StringIO import StringIO # need a dict to set bloody .name field
-from git.util import Iterable
+from git.util import Iterable, join_path_native, to_native_path_linux
from git.config import GitConfigParser, SectionConstraint
-from git.util import join_path_native
from git.exc import InvalidGitRepositoryError, NoSuchPathError
import stat
+import git
import os
import sys
@@ -87,6 +87,7 @@ class Submodule(base.IndexObject, Iterable, Traversable):
type = 'submodule'
__slots__ = ('_parent_commit', '_url', '_branch', '_name', '__weakref__')
+ _cache_attrs = ('path', '_url', '_branch')
def __init__(self, repo, binsha, mode=None, path=None, name = None, parent_commit=None, url=None, branch=None):
"""Initialize this instance with its attributes. We only document the ones
@@ -178,7 +179,7 @@ class Submodule(base.IndexObject, Iterable, Traversable):
def _clear_cache(self):
# clear the possibly changed values
- for name in ('path', '_branch', '_url'):
+ for name in self._cache_attrs:
try:
delattr(self, name)
except AttributeError:
@@ -235,18 +236,19 @@ class Submodule(base.IndexObject, Iterable, Traversable):
path = path[:-1]
# END handle trailing slash
+ # INSTANTIATE INTERMEDIATE SM
sm = cls(repo, cls.NULL_BIN_SHA, cls.k_def_mode, path, name)
if sm.exists():
# reretrieve submodule from tree
return repo.head.commit.tree[path]
# END handle existing
- branch = Head(repo, head.to_full_path(branch))
+ branch = git.Head(repo, git.Head.to_full_path(branch))
has_module = sm.module_exists()
branch_is_default = branch.name == cls.k_head_default
if has_module and url is not None:
if url not in [r.url for r in sm.module().remotes]:
- raise ValueError("Specified URL %s does not match any remote url of the repository at %s" % (url, sm.module_path()))
+ raise ValueError("Specified URL '%s' does not match any remote url of the repository at '%s'" % (url, sm.module_path()))
# END check url
# END verify urls match
@@ -611,14 +613,30 @@ class Submodule(base.IndexObject, Iterable, Traversable):
""":return: True if the submodule exists, False otherwise. Please note that
a submodule may exist (in the .gitmodules file) even though its module
doesn't exist"""
+ # keep attributes for later, and restore them if we have no valid data
+ # this way we do not actually alter the state of the object
+ loc = locals()
+ for attr in self._cache_attrs:
+ if hasattr(self, attr):
+ loc[attr] = getattr(self, attr)
+ # END if we have the attribute cache
+ #END for each attr
self._clear_cache()
+
try:
- self.path
- return True
- except Exception:
- # we raise if the path cannot be restored from configuration
- return False
- # END handle exceptions
+ try:
+ self.path
+ return True
+ except Exception:
+ return False
+ # END handle exceptions
+ finally:
+ for attr in self._cache_attrs:
+ if attr in loc:
+ setattr(self, attr, loc[attr])
+ # END if we have a cache
+ # END reapply each attribute
+ # END handle object state consistency
@property
def branch(self):
diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py
index 6172fed5..b66c4d9f 100644
--- a/test/git/test_submodule.py
+++ b/test/git/test_submodule.py
@@ -99,6 +99,21 @@ class TestSubmodule(TestBase):
# currently there is only one submodule
assert len(list(rwrepo.iter_submodules())) == 1
+ # TEST ADD
+ ###########
+ # preliminary tests
+ # adding existing returns exactly the existing
+ sma = Submodule.add(rwrepo, sm.name, sm.path)
+ assert sma.path == sm.path
+
+ # no url and no module at path fails
+ self.failUnlessRaises(ValueError, Submodule.add, rwrepo, "newsubm", "pathtorepo", url=None)
+
+ # TODO: Test no remote url in existing repository
+
+ # CONTINUE UPDATE
+ #################
+
# lets update it - its a recursive one too
newdir = os.path.join(sm.module_path(), 'dir')
os.makedirs(newdir)
@@ -112,6 +127,15 @@ class TestSubmodule(TestBase):
assert isinstance(sm.module(), git.Repo)
assert sm.module().working_tree_dir == sm.module_path()
+ # INTERLEAVE ADD TEST
+ #####################
+ # url must match the one in the existing repository ( if submodule name suggests a new one )
+ # or we raise
+ self.failUnlessRaises(ValueError, Submodule.add, rwrepo, "newsubm", sm.path, "git://someurl/repo.git")
+
+
+ # CONTINUE UPDATE
+ #################
# we should have setup a tracking branch, which is also active
assert sm.module().head.ref.tracking_branch() is not None