diff options
-rw-r--r-- | bitbake/lib/bb/fetch2/gitsm.py | 116 |
1 files changed, 78 insertions, 38 deletions
diff --git a/bitbake/lib/bb/fetch2/gitsm.py b/bitbake/lib/bb/fetch2/gitsm.py index 11bfa6684f..c172ab1660 100644 --- a/bitbake/lib/bb/fetch2/gitsm.py +++ b/bitbake/lib/bb/fetch2/gitsm.py | |||
@@ -213,61 +213,101 @@ class GitSM(Git): | |||
213 | submodules = self.parse_gitmodules(gitmodules) | 213 | submodules = self.parse_gitmodules(gitmodules) |
214 | self.copy_submodules(submodules, ud, name, dest, d) | 214 | self.copy_submodules(submodules, ud, name, dest, d) |
215 | 215 | ||
216 | def unpack(self, ud, destdir, d): | 216 | def unpack_submodules(self, repo_conf, ud, d): |
217 | Git.unpack(self, ud, destdir, d) | 217 | submodules = [] |
218 | |||
219 | # Copy over the submodules' fetched histories too. | ||
220 | if ud.bareclone: | ||
221 | repo_conf = ud.destdir | ||
222 | else: | ||
223 | repo_conf = os.path.join(ud.destdir, '.git') | ||
224 | |||
225 | update_submodules = False | ||
226 | paths = {} | 218 | paths = {} |
219 | revision = {} | ||
227 | uris = {} | 220 | uris = {} |
228 | local_paths = {} | 221 | local_paths = {} |
222 | |||
229 | for name in ud.names: | 223 | for name in ud.names: |
230 | try: | 224 | try: |
231 | gitmodules = runfetchcmd("%s show HEAD:.gitmodules" % (ud.basecmd), d, quiet=True, workdir=ud.destdir) | 225 | gitmodules = runfetchcmd("%s show %s:.gitmodules" % (ud.basecmd, ud.revisions[name]), d, quiet=True, workdir=ud.destdir) |
232 | except: | 226 | except: |
233 | # No submodules to update | 227 | # No submodules to update |
234 | continue | 228 | continue |
235 | 229 | ||
236 | submodules = self.parse_gitmodules(gitmodules) | 230 | for m, md in self.parse_gitmodules(gitmodules).items(): |
237 | self.copy_submodules(submodules, ud, name, ud.destdir, d) | 231 | submodules.append(m) |
232 | paths[m] = md['path'] | ||
233 | revision[m] = ud.revisions[name] | ||
234 | uris[m] = md['url'] | ||
235 | if uris[m].startswith('..'): | ||
236 | newud = copy.copy(ud) | ||
237 | newud.path = os.path.realpath(os.path.join(newud.path, md['url'])) | ||
238 | uris[m] = Git._get_repo_url(self, newud) | ||
238 | 239 | ||
239 | submodules_queue = [(module, os.path.join(repo_conf, 'modules', md['path'])) for module, md in submodules.items()] | 240 | modules_updated = False |
240 | while len(submodules_queue) != 0: | ||
241 | module, modpath = submodules_queue.pop() | ||
242 | 241 | ||
243 | # add submodule children recursively | 242 | for module in submodules: |
244 | try: | 243 | try: |
245 | gitmodules = runfetchcmd("%s show HEAD:.gitmodules" % (ud.basecmd), d, quiet=True, workdir=modpath) | 244 | module_hash = runfetchcmd("%s ls-tree -z -d %s %s" % (ud.basecmd, revision[module], paths[module]), d, quiet=True, workdir=ud.destdir) |
246 | for m, md in self.parse_gitmodules(gitmodules).items(): | 245 | except: |
247 | submodules_queue.append([m, os.path.join(modpath, 'modules', md['path'])]) | 246 | # If the command fails, we don't have a valid file to check. If it doesn't |
248 | except: | 247 | # fail -- it still might be a failure, see next check... |
249 | # no children | 248 | module_hash = "" |
250 | pass | ||
251 | 249 | ||
250 | if not module_hash: | ||
251 | logger.debug(1, "submodule %s is defined, but is not initialized in the repository. Skipping", module) | ||
252 | continue | ||
252 | 253 | ||
253 | # There are submodules to update | 254 | modules_updated = True |
254 | update_submodules = True | ||
255 | 255 | ||
256 | # Determine (from the submodule) the correct url to reference | 256 | module_hash = module_hash.split()[2] |
257 | try: | ||
258 | output = runfetchcmd("%(basecmd)s config remote.origin.url" % {'basecmd': ud.basecmd}, d, workdir=modpath) | ||
259 | except bb.fetch2.FetchError as e: | ||
260 | # No remote url defined in this submodule | ||
261 | continue | ||
262 | 257 | ||
263 | local_paths[module] = output | 258 | # Build new SRC_URI |
259 | if "://" not in uris[module]: | ||
260 | # It's ssh if the format does NOT have "://", but has a ':' | ||
261 | if ":" in uris[module]: | ||
262 | proto = "ssh" | ||
263 | if ":/" in uris[module]: | ||
264 | url = "gitsm://" + uris[module].replace(':/', '/', 1) | ||
265 | else: | ||
266 | url = "gitsm://" + uris[module].replace(':', '/', 1) | ||
267 | else: # Fall back to 'file' if there is no ':' | ||
268 | proto = "file" | ||
269 | url = "gitsm://" + uris[module] | ||
270 | else: | ||
271 | proto = uris[module].split(':', 1)[0] | ||
272 | url = uris[module].replace('%s:' % proto, 'gitsm:', 1) | ||
264 | 273 | ||
265 | # Setup the local URL properly (like git submodule init or sync would do...) | 274 | url += ';protocol=%s' % proto |
266 | runfetchcmd("%(basecmd)s config submodule.%(module)s.url %(url)s" % {'basecmd': ud.basecmd, 'module': module, 'url' : local_paths[module]}, d, workdir=ud.destdir) | 275 | url += ";name=%s" % module |
276 | url += ";bareclone=1;nobranch=1;subpath=%s" % paths[module] | ||
277 | |||
278 | ld = d.createCopy() | ||
279 | # Not necessary to set SRC_URI, since we're passing the URI to | ||
280 | # Fetch. | ||
281 | #ld.setVar('SRC_URI', url) | ||
282 | ld.setVar('SRCREV_%s' % module, module_hash) | ||
267 | 283 | ||
268 | # Ensure the submodule repository is NOT set to bare, since we're checking it out... | 284 | # Workaround for issues with SRCPV/SRCREV_FORMAT errors |
269 | runfetchcmd("%s config core.bare false" % (ud.basecmd), d, quiet=True, workdir=modpath) | 285 | # error refer to 'multiple' repositories. Only the repository |
286 | # in the original SRC_URI actually matters... | ||
287 | ld.setVar('SRCPV', d.getVar('SRCPV')) | ||
288 | ld.setVar('SRCREV_FORMAT', module) | ||
289 | |||
290 | newfetch = Fetch([url], ld, cache=False) | ||
291 | newfetch.unpack(root=os.path.join(repo_conf, 'modules')) | ||
292 | local_paths[module] = newfetch.localpath(url) | ||
293 | |||
294 | # Correct the submodule references to the local download version... | ||
295 | runfetchcmd("%(basecmd)s config submodule.%(module)s.url %(url)s" % {'basecmd': ud.basecmd, 'module': module, 'url' : local_paths[module]}, d, workdir=ud.destdir) | ||
296 | |||
297 | # Ensure the submodule repository is NOT set to bare, since we're checking it out... | ||
298 | runfetchcmd("%s config core.bare false" % (ud.basecmd), d, quiet=True, workdir=os.path.join(repo_conf, 'modules', paths[module])) | ||
299 | |||
300 | return modules_updated | ||
301 | |||
302 | def unpack(self, ud, destdir, d): | ||
303 | Git.unpack(self, ud, destdir, d) | ||
304 | |||
305 | # Copy over the submodules' fetched histories too. | ||
306 | if ud.bareclone: | ||
307 | repo_conf = ud.destdir | ||
308 | else: | ||
309 | repo_conf = os.path.join(ud.destdir, '.git') | ||
270 | 310 | ||
271 | if update_submodules: | 311 | if self.unpack_submodules(repo_conf, ud, d): |
272 | # Run submodule update, this sets up the directories -- without touching the config | 312 | # Run submodule update, this sets up the directories -- without touching the config |
273 | runfetchcmd("%s submodule update --recursive --no-fetch" % (ud.basecmd), d, quiet=True, workdir=ud.destdir) | 313 | runfetchcmd("%s submodule update --recursive --no-fetch" % (ud.basecmd), d, quiet=True, workdir=ud.destdir) |