diff --git a/project.py b/project.py index 2989e09d..6d8784e1 100644 --- a/project.py +++ b/project.py @@ -34,7 +34,8 @@ from git_config import GitConfig, IsId, GetSchemeFromUrl, GetUrlCookieFile, \ ID_RE from error import GitError, UploadError, DownloadError from error import ManifestInvalidRevisionError, ManifestInvalidPathError -from error import NoManifestException +from error import NoManifestException, ManifestParseError +import git_superproject import platform_utils import progress from repo_trace import IsTrace, Trace @@ -3443,7 +3444,8 @@ class ManifestProject(MetaProject): partial_clone=None, depth=None, clone_filter='blob:none', partial_clone_exclude=None, clone_bundle=None, git_lfs=None, use_superproject=None, verbose=False, current_branch_only=False, - platform='', tags=''): + platform='', tags='', manifest_name='default.xml', + this_manifest_only=False, outer_manifest=True): """Sync the manifest and all submanifests. Args: @@ -3477,12 +3479,45 @@ class ManifestProject(MetaProject): platform: a string, restrict the checkout to projects with the specified platform group. tags: a boolean, whether to fetch tags., + manifest_name: a string, the name of the manifest file to use. + this_manifest_only: a boolean, whether to only operate on the current sub + manifest. + outer_manifest: a boolean, whether to start at the outermost manifest. Returns: a boolean, whether the sync was successful. """ assert _kwargs_only == (), 'Sync only accepts keyword arguments.' + if outer_manifest and self.manifest.is_submanifest: + # In a multi-manifest checkout, use the outer manifest unless we are told + # not to. + return self.client.outer_manifest.manifestProject.Sync( + manifest_url=manifest_url, + manifest_branch=manifest_branch, + standalone_manifest=standalone_manifest, + groups=groups, + platform=platform, + mirror=mirror, + dissociate=dissociate, + reference=reference, + worktree=worktree, + submodules=submodules, + archive=archive, + partial_clone=partial_clone, + clone_filter=clone_filter, + partial_clone_exclude=partial_clone_exclude, + clone_bundle=clone_bundle, + git_lfs=git_lfs, + use_superproject=use_superproject, + verbose=verbose, + current_branch_only=current_branch_only, + tags=tags, + depth=depth, + manifest_name=manifest_name, + this_manifest_only=this_manifest_only, + outer_manifest=False) + # If repo has already been initialized, we take -u with the absence of # --standalone-manifest to mean "transition to a standard repo set up", # which necessitates starting fresh. @@ -3508,7 +3543,7 @@ class ManifestProject(MetaProject): print('fatal: manifest url is required.', file=sys.stderr) return False - if not quiet: + if verbose: print('Downloading manifest from %s' % (GitConfig.ForUser().UrlInsteadOf(manifest_url),), file=sys.stderr) @@ -3700,6 +3735,65 @@ class ManifestProject(MetaProject): print('fatal: cannot create default in manifest', file=sys.stderr) return False + if not manifest_name: + print('fatal: manifest name (-m) is required.', file=sys.stderr) + return False + + try: + self.manifest.Link(manifest_name) + except ManifestParseError as e: + print("fatal: manifest '%s' not available" % manifest_name, + file=sys.stderr) + print('fatal: %s' % str(e), file=sys.stderr) + return False + + # Lastly, clone the superproject. + superproject = git_superproject.Superproject(self.manifest, + self.repodir, + self.git_event_log, + quiet=not verbose) + sync_result = superproject.Sync() + if not sync_result.success: + print('warning: git update of superproject failed, repo sync will not ' + 'use superproject to fetch source; while this error is not fatal, ' + 'and you can continue to run repo sync, please run repo init with ' + 'the --no-use-superproject option to stop seeing this warning', + file=sys.stderr) + if sync_result.fatal and use_superproject is not None: + return False + + if this_manifest_only: + return True + + for submanifest in self.manifest.submanifests.values(): + spec = submanifest.ToSubmanifestSpec(root=self.manifest.outer_client) + submanifest.repo_client.manifestProject.Sync( + manifest_url=spec.manifestUrl, + manifest_branch=spec.revision, + standalone_manifest=standalone_manifest, + groups=self.manifest_groups, + platform=platform, + mirror=mirror, + dissociate=dissociate, + reference=reference, + worktree=worktree, + submodules=submodules, + archive=archive, + partial_clone=partial_clone, + clone_filter=clone_filter, + partial_clone_exclude=partial_clone_exclude, + clone_bundle=clone_bundle, + git_lfs=git_lfs, + use_superproject=use_superproject, + verbose=verbose, + current_branch_only=current_branch_only, + tags=tags, + depth=depth, + manifest_name=spec.manifestName, + this_manifest_only=False, + outer_manifest=False, + ) + return True def _ConfigureDepth(self, depth): diff --git a/subcmds/init.py b/subcmds/init.py index 13085fae..2cb3ff38 100644 --- a/subcmds/init.py +++ b/subcmds/init.py @@ -32,7 +32,7 @@ from wrapper import Wrapper class Init(InteractiveCommand, MirrorSafeCommand): COMMON = True - MULTI_MANIFEST_SUPPORT = False + MULTI_MANIFEST_SUPPORT = True helpSummary = "Initialize a repo client checkout in the current directory" helpUsage = """ %prog [options] [manifest url] @@ -107,26 +107,6 @@ to update the working directory files. return {'REPO_MANIFEST_URL': 'manifest_url', 'REPO_MIRROR_LOCATION': 'reference'} - def _CloneSuperproject(self, opt): - """Clone the superproject based on the superproject's url and branch. - - Args: - opt: Program options returned from optparse. See _Options(). - """ - superproject = git_superproject.Superproject(self.manifest, - self.repodir, - self.git_event_log, - quiet=opt.quiet) - sync_result = superproject.Sync() - if not sync_result.success: - print('warning: git update of superproject failed, repo sync will not ' - 'use superproject to fetch source; while this error is not fatal, ' - 'and you can continue to run repo sync, please run repo init with ' - 'the --no-use-superproject option to stop seeing this warning', - file=sys.stderr) - if sync_result.fatal and opt.use_superproject is not None: - sys.exit(1) - def _SyncManifest(self, opt): """Call manifestProject.Sync with arguments from opt. @@ -154,19 +134,8 @@ to update the working directory files. verbose=opt.verbose, current_branch_only=opt.current_branch_only, tags=opt.tags, - depth=opt.depth): - sys.exit(1) - - def _LinkManifest(self, name): - if not name: - print('fatal: manifest name (-m) is required.', file=sys.stderr) - sys.exit(1) - - try: - self.manifest.Link(name) - except ManifestParseError as e: - print("fatal: manifest '%s' not available" % name, file=sys.stderr) - print('fatal: %s' % str(e), file=sys.stderr) + depth=opt.depth, + manifest_name=opt.manifest_name): sys.exit(1) def _Prompt(self, prompt, value): @@ -343,10 +312,6 @@ to update the working directory files. git_require((2, 15, 0), fail=True, msg='git gc worktree corruption') self._SyncManifest(opt) - self._LinkManifest(opt.manifest_name) - - if self.manifest.manifestProject.use_superproject: - self._CloneSuperproject(opt) if os.isatty(0) and os.isatty(1) and not self.manifest.IsMirror: if opt.config_name or self._ShouldConfigureUser(opt):