@@ -51,41 +51,41 @@ class Submodule(util.IndexObject, Iterable, Traversable):
5151 # this is a bogus type for base class compatability
5252 type = 'submodule'
5353
54- __slots__ = ('_parent_commit' , '_url' , '_branch ' , '_name' , '__weakref__' )
55- _cache_attrs = ('path' , '_url' , '_branch ' )
54+ __slots__ = ('_parent_commit' , '_url' , '_branch_path ' , '_name' , '__weakref__' )
55+ _cache_attrs = ('path' , '_url' , '_branch_path ' )
5656
57- def __init__ (self , repo , binsha , mode = None , path = None , name = None , parent_commit = None , url = None , branch = None ):
57+ def __init__ (self , repo , binsha , mode = None , path = None , name = None , parent_commit = None , url = None , branch_path = None ):
5858 """Initialize this instance with its attributes. We only document the ones
5959 that differ from ``IndexObject``
6060
6161 :param repo: Our parent repository
6262 :param binsha: binary sha referring to a commit in the remote repository, see url parameter
6363 :param parent_commit: see set_parent_commit()
6464 :param url: The url to the remote repository which is the submodule
65- :param branch: Head instance to checkout when cloning the remote repository"""
65+ :param branch_path: full (relative) path to ref to checkout when cloning the remote repository"""
6666 super (Submodule , self ).__init__ (repo , binsha , mode , path )
6767 self .size = 0
6868 if parent_commit is not None :
6969 self ._parent_commit = parent_commit
7070 if url is not None :
7171 self ._url = url
72- if branch is not None :
73- assert isinstance (branch , git . Head )
74- self ._branch = branch
72+ if branch_path is not None :
73+ assert isinstance (branch_path , basestring )
74+ self ._branch_path = branch_path
7575 if name is not None :
7676 self ._name = name
7777
7878 def _set_cache_ (self , attr ):
7979 if attr == '_parent_commit' :
8080 # set a default value, which is the root tree of the current head
8181 self ._parent_commit = self .repo .commit ()
82- elif attr in ('path' , '_url' , '_branch ' ):
82+ elif attr in ('path' , '_url' , '_branch_path ' ):
8383 reader = self .config_reader ()
8484 # default submodule values
8585 self .path = reader .get_value ('path' )
8686 self ._url = reader .get_value ('url' )
8787 # git-python extension values - optional
88- self ._branch = mkhead ( self . repo , reader .get_value (self .k_head_option , self .k_head_default ))
88+ self ._branch_path = reader .get_value (self .k_head_option , git . Head . to_full_path ( self .k_head_default ))
8989 elif attr == '_name' :
9090 raise AttributeError ("Cannot retrieve the name of a submodule if it was not set initially" )
9191 else :
@@ -119,7 +119,7 @@ def __str__(self):
119119 return self ._name
120120
121121 def __repr__ (self ):
122- return "git.%s(name=%s, path=%s, url=%s, branch =%s)" % (type (self ).__name__ , self ._name , self .path , self .url , self .branch )
122+ return "git.%s(name=%s, path=%s, url=%s, branch_path =%s)" % (type (self ).__name__ , self ._name , self .path , self .url , self .branch_path )
123123
124124 @classmethod
125125 def _config_parser (cls , repo , parent_commit , read_only ):
@@ -226,7 +226,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False):
226226 # END handle exceptions
227227 # END handle existing
228228
229- br = mkhead ( repo , branch or cls .k_head_default )
229+ br = git . Head . to_full_path ( str ( branch ) or cls .k_head_default )
230230 has_module = sm .module_exists ()
231231 branch_is_default = branch is None
232232 if has_module and url is not None :
@@ -250,7 +250,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False):
250250 # clone new repo
251251 kwargs = {'n' : no_checkout }
252252 if not branch_is_default :
253- kwargs ['b' ] = str ( br )
253+ kwargs ['b' ] = br
254254 # END setup checkout-branch
255255 mrepo = git .Repo .clone_from (url , path , ** kwargs )
256256 # END verify url
@@ -264,8 +264,8 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False):
264264 sm ._url = url
265265 if not branch_is_default :
266266 # store full path
267- writer .set_value (cls .k_head_option , br . path )
268- sm ._branch = br . path
267+ writer .set_value (cls .k_head_option , br )
268+ sm ._branch_path = br
269269 # END handle path
270270 del (writer )
271271
@@ -327,13 +327,8 @@ def update(self, recursive=False, init=True, to_latest_revision=False):
327327 # see whether we have a valid branch to checkout
328328 try :
329329 # find a remote which has our branch - we try to be flexible
330- remote_branch = find_first_remote_branch (mrepo .remotes , self .branch )
331- local_branch = self .branch
332- if not local_branch .is_valid ():
333- # Setup a tracking configuration - branch doesn't need to
334- # exist to do that
335- local_branch .set_tracking_branch (remote_branch )
336- #END handle local branch
330+ remote_branch = find_first_remote_branch (mrepo .remotes , self .branch_name )
331+ local_branch = mkhead (mrepo , self .branch_path )
337332
338333 # have a valid branch, but no checkout - make sure we can figure
339334 # that out by marking the commit with a null_sha
@@ -349,8 +344,9 @@ def update(self, recursive=False, init=True, to_latest_revision=False):
349344
350345 # make sure HEAD is not detached
351346 mrepo .head .ref = local_branch
347+ mrepo .head .ref .set_tracking_branch (remote_branch )
352348 except IndexError :
353- print >> sys .stderr , "Warning: Failed to checkout tracking branch %s" % self .branch
349+ print >> sys .stderr , "Warning: Failed to checkout tracking branch %s" % self .branch_path
354350 #END handle tracking branch
355351
356352 # NOTE: Have to write the repo config file as well, otherwise
@@ -516,8 +512,8 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False):
516512 :param module: If True, the module we point to will be deleted
517513 as well. If the module is currently on a commit which is not part
518514 of any branch in the remote, if the currently checked out branch
519- is ahead of its tracking branch, if you have modifications in the
520515 working tree, or untracked files,
516+ is ahead of its tracking branch, if you have modifications in the
521517 In case the removal of the repository fails for these reasons, the
522518 submodule status will not have been altered.
523519 If this submodule has child-modules on its own, these will be deleted
@@ -611,6 +607,9 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False):
611607 self .repo .config_writer ().remove_section (sm_section (self .name ))
612608 self .config_writer ().remove_section ()
613609 # END delete configuration
610+
611+ # void our data not to delay invalid access
612+ self ._clear_cache ()
614613
615614 return self
616615
@@ -732,8 +731,22 @@ def exists(self):
732731
733732 @property
734733 def branch (self ):
735- """:return: The branch instance that we are to checkout"""
736- return self ._branch
734+ """:return: The branch instance that we are to checkout
735+ :raise InvalidGitRepositoryError: if our module is not yet checked out"""
736+ return mkhead (self .module (), self ._branch_path )
737+
738+ @property
739+ def branch_path (self ):
740+ """:return: full (relative) path as string to the branch we would checkout
741+ from the remote and track"""
742+ return self ._branch_path
743+
744+ @property
745+ def branch_name (self ):
746+ """:return: the name of the branch, which is the shortest possible branch name"""
747+ # use an instance method, for this we create a temporary Head instance
748+ # which uses a repository that is available at least ( it makes no difference )
749+ return git .Head (self .repo , self ._branch_path ).name
737750
738751 @property
739752 def url (self ):
@@ -814,7 +827,7 @@ def iter_items(cls, repo, parent_commit='HEAD'):
814827 # fill in remaining info - saves time as it doesn't have to be parsed again
815828 sm ._name = n
816829 sm ._parent_commit = pc
817- sm ._branch = mkhead ( repo , b )
830+ sm ._branch_path = git . Head . to_full_path ( b )
818831 sm ._url = u
819832
820833 yield sm
0 commit comments