diff options
Diffstat (limited to 'bitbake')
| -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) |
