@@ -114,11 +114,10 @@ def __init__(self, repo, binsha, mode=None, path=None, name=None, parent_commit=
114114 if branch_path is not None :
115115 assert isinstance (branch_path , str )
116116 self ._branch_path = branch_path
117- if name is not None :
118- self ._name = name
117+ self ._name = name
119118
120119 def _set_cache_ (self , attr ):
121- if attr in ('path' , '_url' , '_branch_path' , '_name' ):
120+ if attr in ('path' , '_url' , '_branch_path' ):
122121 reader = self .config_reader ()
123122 # default submodule values
124123 try :
@@ -134,12 +133,6 @@ def _set_cache_(self, attr):
134133 self ._url = reader .get ('url' )
135134 # git-python extension values - optional
136135 self ._branch_path = reader .get_value (self .k_head_option , git .Head .to_full_path (self .k_head_default ))
137- section_name = reader ._section_name
138- m = re .match (SM_SECTION_NAME_REGEX , section_name )
139- if not m :
140- raise RuntimeError ('Unexpected submodule section name in %s: %s' % (reader .file_or_files , section_name ))
141- name = m ['name' ]
142- self ._name = name
143136 else :
144137 super (Submodule , self )._set_cache_ (attr )
145138 # END handle attribute name
@@ -172,11 +165,11 @@ def __hash__(self):
172165 return hash (self ._name )
173166
174167 def __str__ (self ):
175- return self ._name
168+ return self .name
176169
177170 def __repr__ (self ):
178- return "git.%s(name=%s, path=%s, url=%s, branch_path=%s)" \
179- % (type (self ).__name__ , self ._name , self .path , self .url , self .branch_path )
171+ return "git.%s(name=%s, path=%s, url=%s, branch_path=%s)" \
172+ % (type (self ).__name__ , self .name , self .path , self .url , self .branch_path )
180173
181174 @classmethod
182175 def _config_parser (cls , repo , parent_commit , read_only ):
@@ -228,6 +221,51 @@ def _sio_modules(cls, parent_commit):
228221 sio .name = cls .k_modules_file
229222 return sio
230223
224+ def _lookup_name_by_config_section_path (self ):
225+ try :
226+ pc = self .parent_commit
227+ except ValueError :
228+ pc = None
229+
230+ parser = self ._config_parser (self .repo , pc , read_only = True )
231+
232+ name = None
233+ config_file = parser ._file_or_files
234+ parser .read ()
235+ parser_sections = parser ._sections
236+ section_items = list (parser_sections .items ())
237+ for section_name , sections in section_items :
238+ m = re .match (SM_SECTION_NAME_REGEX , section_name )
239+ if not m :
240+ raise RuntimeError ('Unrecognized submodule section line: %s' % section_name )
241+ cur_name = m ['name' ]
242+ if self .path == sections ['path' ]:
243+ # if [section['path'] == self.path for section in sections]:
244+ if name is None :
245+ name = cur_name
246+ else :
247+ raise AttributeError (
248+ 'Submodule name not set, and multiple sections matching path (%s) found in config file %s (commit: %s): %s' % (
249+ self .path ,
250+ config_file ,
251+ pc or '???' ,
252+ ',' .join ([name , cur_name ]),
253+ )
254+ )
255+ else :
256+ print ('path %s not found in %d sections named %s' % (self .path , len (sections ), section_name ))
257+ if name is None :
258+ raise AttributeError (
259+ 'Submodule name not set, and no section matching path (%s) found in config file %s (commit: %s) with sections %s' % (
260+ self .path ,
261+ config_file ,
262+ pc .hexsha or '???' ,
263+ ',' .join ([k for k , _ in section_items ])
264+ )
265+ )
266+
267+ self ._name = name
268+
231269 def _config_parser_constrained (self , read_only ):
232270 """:return: Config Parser constrained to our submodule in read or write mode"""
233271 try :
@@ -1162,6 +1200,8 @@ def name(self):
11621200 used for remotes, which allows to change the path of the submodule
11631201 easily
11641202 """
1203+ if self ._name is None :
1204+ self ._lookup_name_by_config_section_path ()
11651205 return self ._name
11661206
11671207 def config_reader (self ):
0 commit comments