|
1 | 1 | import base
|
2 | 2 | from util import Traversable
|
3 | 3 | from StringIO import StringIO # need a dict to set bloody .name field
|
4 |
| -from git.util import Iterable |
| 4 | +from git.util import Iterable, join_path_native, to_native_path_linux |
5 | 5 | from git.config import GitConfigParser, SectionConstraint
|
6 |
| -from git.util import join_path_native |
7 | 6 | from git.exc import InvalidGitRepositoryError, NoSuchPathError
|
8 | 7 | import stat
|
| 8 | +import git |
9 | 9 |
|
10 | 10 | import os
|
11 | 11 | import sys
|
@@ -87,6 +87,7 @@ class Submodule(base.IndexObject, Iterable, Traversable):
|
87 | 87 | type = 'submodule'
|
88 | 88 |
|
89 | 89 | __slots__ = ('_parent_commit', '_url', '_branch', '_name', '__weakref__')
|
| 90 | + _cache_attrs = ('path', '_url', '_branch') |
90 | 91 |
|
91 | 92 | def __init__(self, repo, binsha, mode=None, path=None, name = None, parent_commit=None, url=None, branch=None):
|
92 | 93 | """Initialize this instance with its attributes. We only document the ones
|
@@ -178,7 +179,7 @@ def _config_parser(cls, repo, parent_commit, read_only):
|
178 | 179 |
|
179 | 180 | def _clear_cache(self):
|
180 | 181 | # clear the possibly changed values
|
181 |
| - for name in ('path', '_branch', '_url'): |
| 182 | + for name in self._cache_attrs: |
182 | 183 | try:
|
183 | 184 | delattr(self, name)
|
184 | 185 | except AttributeError:
|
@@ -235,18 +236,19 @@ def add(cls, repo, name, path, url=None, branch=k_head_default, no_checkout=Fals
|
235 | 236 | path = path[:-1]
|
236 | 237 | # END handle trailing slash
|
237 | 238 |
|
| 239 | + # INSTANTIATE INTERMEDIATE SM |
238 | 240 | sm = cls(repo, cls.NULL_BIN_SHA, cls.k_def_mode, path, name)
|
239 | 241 | if sm.exists():
|
240 | 242 | # reretrieve submodule from tree
|
241 | 243 | return repo.head.commit.tree[path]
|
242 | 244 | # END handle existing
|
243 | 245 |
|
244 |
| - branch = Head(repo, head.to_full_path(branch)) |
| 246 | + branch = git.Head(repo, git.Head.to_full_path(branch)) |
245 | 247 | has_module = sm.module_exists()
|
246 | 248 | branch_is_default = branch.name == cls.k_head_default
|
247 | 249 | if has_module and url is not None:
|
248 | 250 | if url not in [r.url for r in sm.module().remotes]:
|
249 |
| - raise ValueError("Specified URL %s does not match any remote url of the repository at %s" % (url, sm.module_path())) |
| 251 | + raise ValueError("Specified URL '%s' does not match any remote url of the repository at '%s'" % (url, sm.module_path())) |
250 | 252 | # END check url
|
251 | 253 | # END verify urls match
|
252 | 254 |
|
@@ -611,14 +613,30 @@ def exists(self):
|
611 | 613 | """:return: True if the submodule exists, False otherwise. Please note that
|
612 | 614 | a submodule may exist (in the .gitmodules file) even though its module
|
613 | 615 | doesn't exist"""
|
| 616 | + # keep attributes for later, and restore them if we have no valid data |
| 617 | + # this way we do not actually alter the state of the object |
| 618 | + loc = locals() |
| 619 | + for attr in self._cache_attrs: |
| 620 | + if hasattr(self, attr): |
| 621 | + loc[attr] = getattr(self, attr) |
| 622 | + # END if we have the attribute cache |
| 623 | + #END for each attr |
614 | 624 | self._clear_cache()
|
| 625 | + |
615 | 626 | try:
|
616 |
| - self.path |
617 |
| - return True |
618 |
| - except Exception: |
619 |
| - # we raise if the path cannot be restored from configuration |
620 |
| - return False |
621 |
| - # END handle exceptions |
| 627 | + try: |
| 628 | + self.path |
| 629 | + return True |
| 630 | + except Exception: |
| 631 | + return False |
| 632 | + # END handle exceptions |
| 633 | + finally: |
| 634 | + for attr in self._cache_attrs: |
| 635 | + if attr in loc: |
| 636 | + setattr(self, attr, loc[attr]) |
| 637 | + # END if we have a cache |
| 638 | + # END reapply each attribute |
| 639 | + # END handle object state consistency |
622 | 640 |
|
623 | 641 | @property
|
624 | 642 | def branch(self):
|
|
0 commit comments