mirror of
https://gerrit.googlesource.com/git-repo
synced 2025-06-28 20:17:26 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
4c11aebeb9 | |||
b90a422ab6 | |||
a46047a822 | |||
5fa912b0d1 | |||
4ada043dc0 | |||
d8de29c447 | |||
2cc3ab7663 |
@ -238,8 +238,8 @@ class Superproject(object):
|
||||
f'{self._manifest.manifestFile}')
|
||||
return SyncResult(False, False)
|
||||
|
||||
print('NOTICE: --use-superproject is in beta; report any issues to the '
|
||||
'address described in `repo version`', file=sys.stderr)
|
||||
_PrintBetaNotice()
|
||||
|
||||
should_exit = True
|
||||
if not self._remote_url:
|
||||
self._LogWarning(f'superproject URL is not defined in manifest: '
|
||||
@ -364,6 +364,13 @@ class Superproject(object):
|
||||
return UpdateProjectsResult(manifest_path, False)
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=10)
|
||||
def _PrintBetaNotice():
|
||||
"""Print the notice of beta status."""
|
||||
print('NOTICE: --use-superproject is in beta; report any issues to the '
|
||||
'address described in `repo version`', file=sys.stderr)
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def _UseSuperprojectFromConfiguration():
|
||||
"""Returns the user choice of whether to use superproject."""
|
||||
@ -408,16 +415,26 @@ def _UseSuperprojectFromConfiguration():
|
||||
return False
|
||||
|
||||
|
||||
def PrintMessages(opt, manifest):
|
||||
"""Returns a boolean if error/warning messages are to be printed."""
|
||||
return opt.use_superproject is not None or bool(manifest.superproject)
|
||||
def PrintMessages(use_superproject, manifest):
|
||||
"""Returns a boolean if error/warning messages are to be printed.
|
||||
|
||||
Args:
|
||||
use_superproject: option value from optparse.
|
||||
manifest: manifest to use.
|
||||
"""
|
||||
return use_superproject is not None or bool(manifest.superproject)
|
||||
|
||||
|
||||
def UseSuperproject(opt, manifest):
|
||||
"""Returns a boolean if use-superproject option is enabled."""
|
||||
def UseSuperproject(use_superproject, manifest):
|
||||
"""Returns a boolean if use-superproject option is enabled.
|
||||
|
||||
if opt.use_superproject is not None:
|
||||
return opt.use_superproject
|
||||
Args:
|
||||
use_superproject: option value from optparse.
|
||||
manifest: manifest to use.
|
||||
"""
|
||||
|
||||
if use_superproject is not None:
|
||||
return use_superproject
|
||||
else:
|
||||
client_value = manifest.manifestProject.use_superproject
|
||||
if client_value is not None:
|
||||
|
2
main.py
2
main.py
@ -310,7 +310,7 @@ class _Repo(object):
|
||||
# (sub)manifest, and then any child submanifests.
|
||||
result = cmd.Execute(copts, cargs)
|
||||
for submanifest in repo_client.manifest.submanifests.values():
|
||||
spec = submanifest.ToSubmanifestSpec(root=repo_client.outer_client)
|
||||
spec = submanifest.ToSubmanifestSpec()
|
||||
gopts.submanifest_path = submanifest.repo_client.path_prefix
|
||||
child_argv = argv[:]
|
||||
child_argv.append('--no-outer-manifest')
|
||||
|
124
manifest_xml.py
124
manifest_xml.py
@ -215,8 +215,9 @@ class _XmlSubmanifest:
|
||||
manifestName: a string, the submanifest file name.
|
||||
groups: a list of strings, the groups to add to all projects in the submanifest.
|
||||
path: a string, the relative path for the submanifest checkout.
|
||||
parent: an XmlManifest, the parent manifest.
|
||||
annotations: (derived) a list of annotations.
|
||||
present: (derived) a boolean, whether the submanifest's manifest file is present.
|
||||
present: (derived) a boolean, whether the sub manifest file is present.
|
||||
"""
|
||||
def __init__(self,
|
||||
name,
|
||||
@ -234,6 +235,7 @@ class _XmlSubmanifest:
|
||||
self.manifestName = manifestName
|
||||
self.groups = groups
|
||||
self.path = path
|
||||
self.parent = parent
|
||||
self.annotations = []
|
||||
outer_client = parent._outer_client or parent
|
||||
if self.remote and not self.project:
|
||||
@ -268,10 +270,10 @@ class _XmlSubmanifest:
|
||||
def __ne__(self, other):
|
||||
return not self.__eq__(other)
|
||||
|
||||
def ToSubmanifestSpec(self, root):
|
||||
def ToSubmanifestSpec(self):
|
||||
"""Return a SubmanifestSpec object, populating attributes"""
|
||||
mp = root.manifestProject
|
||||
remote = root.remotes[self.remote or root.default.remote.name]
|
||||
mp = self.parent.manifestProject
|
||||
remote = self.parent.remotes[self.remote or self.parent.default.remote.name]
|
||||
# If a project was given, generate the url from the remote and project.
|
||||
# If not, use this manifestProject's url.
|
||||
if self.project:
|
||||
@ -348,6 +350,11 @@ class XmlManifest(object):
|
||||
if manifest_file != os.path.abspath(manifest_file):
|
||||
raise ManifestParseError('manifest_file must be abspath')
|
||||
self.manifestFile = manifest_file
|
||||
if not outer_client or outer_client == self:
|
||||
# manifestFileOverrides only exists in the outer_client's manifest, since
|
||||
# that is the only instance left when Unload() is called on the outer
|
||||
# manifest.
|
||||
self.manifestFileOverrides = {}
|
||||
self.local_manifests = local_manifests
|
||||
self._load_local_manifests = True
|
||||
self.parent_groups = parent_groups
|
||||
@ -396,14 +403,10 @@ class XmlManifest(object):
|
||||
if not os.path.isfile(path):
|
||||
raise ManifestParseError('manifest %s not found' % name)
|
||||
|
||||
old = self.manifestFile
|
||||
try:
|
||||
self._load_local_manifests = load_local_manifests
|
||||
self.manifestFile = path
|
||||
self.Unload()
|
||||
self._Load()
|
||||
finally:
|
||||
self.manifestFile = old
|
||||
self._load_local_manifests = load_local_manifests
|
||||
self._outer_client.manifestFileOverrides[self.path_prefix] = path
|
||||
self.Unload()
|
||||
self._Load()
|
||||
|
||||
def Link(self, name):
|
||||
"""Update the repo metadata to use a different manifest.
|
||||
@ -880,6 +883,10 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
|
||||
exclude = self.manifest.manifestProject.partial_clone_exclude or ''
|
||||
return set(x.strip() for x in exclude.split(','))
|
||||
|
||||
def SetManifestOverride(self, path):
|
||||
"""Override manifestFile. The caller must call Unload()"""
|
||||
self._outer_client.manifest.manifestFileOverrides[self.path_prefix] = path
|
||||
|
||||
@property
|
||||
def UseLocalManifests(self):
|
||||
return self._load_local_manifests
|
||||
@ -1005,57 +1012,66 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
|
||||
# This will load all clients.
|
||||
self._outer_client._Load(initial_client=self)
|
||||
|
||||
m = self.manifestProject
|
||||
b = m.GetBranch(m.CurrentBranch).merge
|
||||
if b is not None and b.startswith(R_HEADS):
|
||||
b = b[len(R_HEADS):]
|
||||
self.branch = b
|
||||
|
||||
parent_groups = self.parent_groups
|
||||
if self.path_prefix:
|
||||
parent_groups = f'{SUBMANIFEST_GROUP_PREFIX}:path:{self.path_prefix},{parent_groups}'
|
||||
|
||||
# The manifestFile was specified by the user which is why we allow include
|
||||
# paths to point anywhere.
|
||||
nodes = []
|
||||
nodes.append(self._ParseManifestXml(
|
||||
self.manifestFile, self.manifestProject.worktree,
|
||||
parent_groups=parent_groups, restrict_includes=False))
|
||||
|
||||
if self._load_local_manifests and self.local_manifests:
|
||||
try:
|
||||
for local_file in sorted(platform_utils.listdir(self.local_manifests)):
|
||||
if local_file.endswith('.xml'):
|
||||
local = os.path.join(self.local_manifests, local_file)
|
||||
# Since local manifests are entirely managed by the user, allow
|
||||
# them to point anywhere the user wants.
|
||||
local_group = f'{LOCAL_MANIFEST_GROUP_PREFIX}:{local_file[:-4]}'
|
||||
nodes.append(self._ParseManifestXml(
|
||||
local, self.subdir,
|
||||
parent_groups=f'{local_group},{parent_groups}',
|
||||
restrict_includes=False))
|
||||
except OSError:
|
||||
pass
|
||||
savedManifestFile = self.manifestFile
|
||||
override = self._outer_client.manifestFileOverrides.get(self.path_prefix)
|
||||
if override:
|
||||
self.manifestFile = override
|
||||
|
||||
try:
|
||||
self._ParseManifest(nodes)
|
||||
except ManifestParseError as e:
|
||||
# There was a problem parsing, unload ourselves in case they catch
|
||||
# this error and try again later, we will show the correct error
|
||||
self.Unload()
|
||||
raise e
|
||||
m = self.manifestProject
|
||||
b = m.GetBranch(m.CurrentBranch).merge
|
||||
if b is not None and b.startswith(R_HEADS):
|
||||
b = b[len(R_HEADS):]
|
||||
self.branch = b
|
||||
|
||||
if self.IsMirror:
|
||||
self._AddMetaProjectMirror(self.repoProject)
|
||||
self._AddMetaProjectMirror(self.manifestProject)
|
||||
parent_groups = self.parent_groups
|
||||
if self.path_prefix:
|
||||
parent_groups = f'{SUBMANIFEST_GROUP_PREFIX}:path:{self.path_prefix},{parent_groups}'
|
||||
|
||||
self._loaded = True
|
||||
# The manifestFile was specified by the user which is why we allow include
|
||||
# paths to point anywhere.
|
||||
nodes = []
|
||||
nodes.append(self._ParseManifestXml(
|
||||
self.manifestFile, self.manifestProject.worktree,
|
||||
parent_groups=parent_groups, restrict_includes=False))
|
||||
|
||||
if self._load_local_manifests and self.local_manifests:
|
||||
try:
|
||||
for local_file in sorted(platform_utils.listdir(self.local_manifests)):
|
||||
if local_file.endswith('.xml'):
|
||||
local = os.path.join(self.local_manifests, local_file)
|
||||
# Since local manifests are entirely managed by the user, allow
|
||||
# them to point anywhere the user wants.
|
||||
local_group = f'{LOCAL_MANIFEST_GROUP_PREFIX}:{local_file[:-4]}'
|
||||
nodes.append(self._ParseManifestXml(
|
||||
local, self.subdir,
|
||||
parent_groups=f'{local_group},{parent_groups}',
|
||||
restrict_includes=False))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
try:
|
||||
self._ParseManifest(nodes)
|
||||
except ManifestParseError as e:
|
||||
# There was a problem parsing, unload ourselves in case they catch
|
||||
# this error and try again later, we will show the correct error
|
||||
self.Unload()
|
||||
raise e
|
||||
|
||||
if self.IsMirror:
|
||||
self._AddMetaProjectMirror(self.repoProject)
|
||||
self._AddMetaProjectMirror(self.manifestProject)
|
||||
|
||||
self._loaded = True
|
||||
finally:
|
||||
if override:
|
||||
self.manifestFile = savedManifestFile
|
||||
|
||||
# Now that we have loaded this manifest, load any submanifest manifests
|
||||
# as well. We need to do this after self._loaded is set to avoid looping.
|
||||
for name in self._submanifests:
|
||||
tree = self._submanifests[name]
|
||||
spec = tree.ToSubmanifestSpec(self)
|
||||
spec = tree.ToSubmanifestSpec()
|
||||
present = os.path.exists(os.path.join(self.subdir, MANIFEST_FILE_NAME))
|
||||
if present and tree.present and not tree.repo_client:
|
||||
if initial_client and initial_client.topdir == self.topdir:
|
||||
|
27
progress.py
27
progress.py
@ -24,6 +24,11 @@ _NOT_TTY = not os.isatty(2)
|
||||
# column 0.
|
||||
CSI_ERASE_LINE = '\x1b[2K'
|
||||
|
||||
# This will erase all content in the current line after the cursor. This is
|
||||
# useful for partial updates & progress messages as the terminal can display
|
||||
# it better.
|
||||
CSI_ERASE_LINE_AFTER = '\x1b[K'
|
||||
|
||||
|
||||
def duration_str(total):
|
||||
"""A less noisy timedelta.__str__.
|
||||
@ -85,10 +90,10 @@ class Progress(object):
|
||||
return
|
||||
|
||||
if self._total <= 0:
|
||||
sys.stderr.write('%s\r%s: %d,' % (
|
||||
CSI_ERASE_LINE,
|
||||
sys.stderr.write('\r%s: %d,%s' % (
|
||||
self._title,
|
||||
self._done))
|
||||
self._done,
|
||||
CSI_ERASE_LINE_AFTER))
|
||||
sys.stderr.flush()
|
||||
else:
|
||||
p = (100 * self._done) / self._total
|
||||
@ -96,14 +101,14 @@ class Progress(object):
|
||||
jobs = '[%d job%s] ' % (self._active, 's' if self._active > 1 else '')
|
||||
else:
|
||||
jobs = ''
|
||||
sys.stderr.write('%s\r%s: %2d%% %s(%d%s/%d%s)%s%s%s' % (
|
||||
CSI_ERASE_LINE,
|
||||
sys.stderr.write('\r%s: %2d%% %s(%d%s/%d%s)%s%s%s%s' % (
|
||||
self._title,
|
||||
p,
|
||||
jobs,
|
||||
self._done, self._units,
|
||||
self._total, self._units,
|
||||
' ' if msg else '', msg,
|
||||
CSI_ERASE_LINE_AFTER,
|
||||
'\n' if self._print_newline else ''))
|
||||
sys.stderr.flush()
|
||||
|
||||
@ -113,19 +118,19 @@ class Progress(object):
|
||||
|
||||
duration = duration_str(time() - self._start)
|
||||
if self._total <= 0:
|
||||
sys.stderr.write('%s\r%s: %d, done in %s\n' % (
|
||||
CSI_ERASE_LINE,
|
||||
sys.stderr.write('\r%s: %d, done in %s%s\n' % (
|
||||
self._title,
|
||||
self._done,
|
||||
duration))
|
||||
duration,
|
||||
CSI_ERASE_LINE_AFTER))
|
||||
sys.stderr.flush()
|
||||
else:
|
||||
p = (100 * self._done) / self._total
|
||||
sys.stderr.write('%s\r%s: %3d%% (%d%s/%d%s), done in %s\n' % (
|
||||
CSI_ERASE_LINE,
|
||||
sys.stderr.write('\r%s: %3d%% (%d%s/%d%s), done in %s%s\n' % (
|
||||
self._title,
|
||||
p,
|
||||
self._done, self._units,
|
||||
self._total, self._units,
|
||||
duration))
|
||||
duration,
|
||||
CSI_ERASE_LINE_AFTER))
|
||||
sys.stderr.flush()
|
||||
|
36
project.py
36
project.py
@ -3371,67 +3371,72 @@ class ManifestProject(MetaProject):
|
||||
@property
|
||||
def reference(self):
|
||||
"""The --reference for this manifest."""
|
||||
self.config.GetString('repo.reference')
|
||||
return self.config.GetString('repo.reference')
|
||||
|
||||
@property
|
||||
def dissociate(self):
|
||||
"""Whether to dissociate."""
|
||||
self.config.GetBoolean('repo.dissociate')
|
||||
return self.config.GetBoolean('repo.dissociate')
|
||||
|
||||
@property
|
||||
def archive(self):
|
||||
"""Whether we use archive."""
|
||||
self.config.GetBoolean('repo.archive')
|
||||
return self.config.GetBoolean('repo.archive')
|
||||
|
||||
@property
|
||||
def mirror(self):
|
||||
"""Whether we use mirror."""
|
||||
self.config.GetBoolean('repo.mirror')
|
||||
return self.config.GetBoolean('repo.mirror')
|
||||
|
||||
@property
|
||||
def use_worktree(self):
|
||||
"""Whether we use worktree."""
|
||||
self.config.GetBoolean('repo.worktree')
|
||||
return self.config.GetBoolean('repo.worktree')
|
||||
|
||||
@property
|
||||
def clone_bundle(self):
|
||||
"""Whether we use clone_bundle."""
|
||||
self.config.GetBoolean('repo.clonebundle')
|
||||
return self.config.GetBoolean('repo.clonebundle')
|
||||
|
||||
@property
|
||||
def submodules(self):
|
||||
"""Whether we use submodules."""
|
||||
self.config.GetBoolean('repo.submodules')
|
||||
return self.config.GetBoolean('repo.submodules')
|
||||
|
||||
@property
|
||||
def git_lfs(self):
|
||||
"""Whether we use git_lfs."""
|
||||
self.config.GetBoolean('repo.git-lfs')
|
||||
return self.config.GetBoolean('repo.git-lfs')
|
||||
|
||||
@property
|
||||
def use_superproject(self):
|
||||
"""Whether we use superproject."""
|
||||
self.config.GetBoolean('repo.superproject')
|
||||
return self.config.GetBoolean('repo.superproject')
|
||||
|
||||
@property
|
||||
def partial_clone(self):
|
||||
"""Whether this is a partial clone."""
|
||||
self.config.GetBoolean('repo.partialclone')
|
||||
return self.config.GetBoolean('repo.partialclone')
|
||||
|
||||
@property
|
||||
def depth(self):
|
||||
"""Partial clone depth."""
|
||||
self.config.GetString('repo.depth')
|
||||
return self.config.GetString('repo.depth')
|
||||
|
||||
@property
|
||||
def clone_filter(self):
|
||||
"""The clone filter."""
|
||||
self.config.GetString('repo.clonefilter')
|
||||
return self.config.GetString('repo.clonefilter')
|
||||
|
||||
@property
|
||||
def partial_clone_exclude(self):
|
||||
"""Partial clone exclude string"""
|
||||
self.config.GetBoolean('repo.partialcloneexclude')
|
||||
return self.config.GetBoolean('repo.partialcloneexclude')
|
||||
|
||||
@property
|
||||
def manifest_platform(self):
|
||||
"""The --platform argument from `repo init`."""
|
||||
return self.config.GetString('manifest.platform')
|
||||
|
||||
@property
|
||||
def _platform_name(self):
|
||||
@ -3479,7 +3484,7 @@ class ManifestProject(MetaProject):
|
||||
platform: a string, restrict the checkout to projects with the specified
|
||||
platform group.
|
||||
git_event_log: an EventLog, for git tracing.
|
||||
tags: a boolean, whether to fetch tags.,
|
||||
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.
|
||||
@ -3620,6 +3625,7 @@ class ManifestProject(MetaProject):
|
||||
elif platform != 'none':
|
||||
print('fatal: invalid platform flag', file=sys.stderr)
|
||||
return False
|
||||
self.config.SetString('manifest.platform', platform)
|
||||
|
||||
groups = [x for x in groups if x]
|
||||
groupstr = ','.join(groups)
|
||||
@ -3754,7 +3760,7 @@ class ManifestProject(MetaProject):
|
||||
|
||||
if not this_manifest_only:
|
||||
for submanifest in self.manifest.submanifests.values():
|
||||
spec = submanifest.ToSubmanifestSpec(root=self.manifest.outer_client)
|
||||
spec = submanifest.ToSubmanifestSpec()
|
||||
submanifest.repo_client.manifestProject.Sync(
|
||||
manifest_url=spec.manifestUrl,
|
||||
manifest_branch=spec.revision,
|
||||
|
@ -84,6 +84,11 @@ REPO_PROJECT is set to the unique name of the project.
|
||||
|
||||
REPO_PATH is the path relative the the root of the client.
|
||||
|
||||
REPO_OUTERPATH is the path of the sub manifest's root relative to the root of
|
||||
the client.
|
||||
|
||||
REPO_INNERPATH is the path relative to the root of the sub manifest.
|
||||
|
||||
REPO_REMOTE is the name of the remote system from the manifest.
|
||||
|
||||
REPO_LREV is the name of the revision from the manifest, translated
|
||||
@ -290,8 +295,9 @@ def DoWork(project, mirror, opt, cmd, shell, cnt, config):
|
||||
env[name] = val
|
||||
|
||||
setenv('REPO_PROJECT', project.name)
|
||||
setenv('REPO_PATH', project.relpath)
|
||||
setenv('REPO_OUTERPATH', project.RelPath(local=opt.this_manifest_only))
|
||||
setenv('REPO_OUTERPATH', project.manifest.path_prefix)
|
||||
setenv('REPO_INNERPATH', project.relpath)
|
||||
setenv('REPO_PATH', project.RelPath(local=opt.this_manifest_only))
|
||||
setenv('REPO_REMOTE', project.remote.name)
|
||||
try:
|
||||
# If we aren't in a fully synced state and we don't have the ref the manifest
|
||||
|
@ -260,6 +260,9 @@ to update the working directory files.
|
||||
if opt.use_superproject is not None:
|
||||
self.OptionParser.error('--mirror and --use-superproject cannot be '
|
||||
'used together.')
|
||||
if opt.archive and opt.use_superproject is not None:
|
||||
self.OptionParser.error('--archive and --use-superproject cannot be used '
|
||||
'together.')
|
||||
|
||||
if opt.standalone_manifest and (opt.manifest_branch or
|
||||
opt.manifest_name != 'default.xml'):
|
||||
|
152
subcmds/sync.py
152
subcmds/sync.py
@ -170,9 +170,9 @@ later is required to fix a server side protocol bug.
|
||||
PARALLEL_JOBS = 1
|
||||
|
||||
def _CommonOptions(self, p):
|
||||
if self.manifest:
|
||||
if self.outer_client and self.outer_client.manifest:
|
||||
try:
|
||||
self.PARALLEL_JOBS = self.manifest.default.sync_j
|
||||
self.PARALLEL_JOBS = self.outer_client.manifest.default.sync_j
|
||||
except ManifestParseError:
|
||||
pass
|
||||
super()._CommonOptions(p)
|
||||
@ -270,25 +270,32 @@ later is required to fix a server side protocol bug.
|
||||
dest='repo_upgraded', action='store_true',
|
||||
help=SUPPRESS_HELP)
|
||||
|
||||
def _GetBranch(self):
|
||||
"""Returns the branch name for getting the approved manifest."""
|
||||
p = self.manifest.manifestProject
|
||||
b = p.GetBranch(p.CurrentBranch)
|
||||
def _GetBranch(self, manifest_project):
|
||||
"""Returns the branch name for getting the approved smartsync manifest.
|
||||
|
||||
Args:
|
||||
manifest_project: the manifestProject to query.
|
||||
"""
|
||||
b = manifest_project.GetBranch(manifest_project.CurrentBranch)
|
||||
branch = b.merge
|
||||
if branch.startswith(R_HEADS):
|
||||
branch = branch[len(R_HEADS):]
|
||||
return branch
|
||||
|
||||
def _GetCurrentBranchOnly(self, opt):
|
||||
def _GetCurrentBranchOnly(self, opt, manifest):
|
||||
"""Returns whether current-branch or use-superproject options are enabled.
|
||||
|
||||
Args:
|
||||
opt: Program options returned from optparse. See _Options().
|
||||
manifest: The manifest to use.
|
||||
|
||||
Returns:
|
||||
True if a superproject is requested, otherwise the value of the
|
||||
current_branch option (True, False or None).
|
||||
"""
|
||||
return git_superproject.UseSuperproject(opt, self.manifest) or opt.current_branch_only
|
||||
return git_superproject.UseSuperproject(opt.use_superproject, manifest) or opt.current_branch_only
|
||||
|
||||
def _UpdateProjectsRevisionId(self, opt, args, load_local_manifests, superproject_logging_data):
|
||||
def _UpdateProjectsRevisionId(self, opt, args, load_local_manifests, superproject_logging_data, manifest):
|
||||
"""Update revisionId of every project with the SHA from superproject.
|
||||
|
||||
This function updates each project's revisionId with SHA from superproject.
|
||||
@ -300,18 +307,20 @@ later is required to fix a server side protocol bug.
|
||||
docstring for details.
|
||||
load_local_manifests: Whether to load local manifests.
|
||||
superproject_logging_data: A dictionary of superproject data that is to be logged.
|
||||
manifest: The manifest to use.
|
||||
|
||||
Returns:
|
||||
Returns path to the overriding manifest file instead of None.
|
||||
"""
|
||||
superproject = self.manifest.superproject
|
||||
superproject.SetQuiet(opt.quiet)
|
||||
print_messages = git_superproject.PrintMessages(opt, self.manifest)
|
||||
print_messages = git_superproject.PrintMessages(opt.use_superproject,
|
||||
self.manifest)
|
||||
superproject.SetPrintMessages(print_messages)
|
||||
if opt.local_only:
|
||||
manifest_path = superproject.manifest_path
|
||||
if manifest_path:
|
||||
self._ReloadManifest(manifest_path, load_local_manifests)
|
||||
self._ReloadManifest(manifest_path, manifest, load_local_manifests)
|
||||
return manifest_path
|
||||
|
||||
all_projects = self.GetProjects(args,
|
||||
@ -322,7 +331,7 @@ later is required to fix a server side protocol bug.
|
||||
manifest_path = update_result.manifest_path
|
||||
superproject_logging_data['updatedrevisionid'] = bool(manifest_path)
|
||||
if manifest_path:
|
||||
self._ReloadManifest(manifest_path, load_local_manifests)
|
||||
self._ReloadManifest(manifest_path, manifest, load_local_manifests)
|
||||
else:
|
||||
if print_messages:
|
||||
print('warning: Update of revisionId from superproject has failed, '
|
||||
@ -365,16 +374,16 @@ later is required to fix a server side protocol bug.
|
||||
quiet=opt.quiet,
|
||||
verbose=opt.verbose,
|
||||
output_redir=buf,
|
||||
current_branch_only=self._GetCurrentBranchOnly(opt),
|
||||
current_branch_only=self._GetCurrentBranchOnly(opt, project.manifest),
|
||||
force_sync=opt.force_sync,
|
||||
clone_bundle=opt.clone_bundle,
|
||||
tags=opt.tags, archive=self.manifest.IsArchive,
|
||||
tags=opt.tags, archive=project.manifest.IsArchive,
|
||||
optimized_fetch=opt.optimized_fetch,
|
||||
retry_fetches=opt.retry_fetches,
|
||||
prune=opt.prune,
|
||||
ssh_proxy=self.ssh_proxy,
|
||||
clone_filter=self.manifest.CloneFilter,
|
||||
partial_clone_exclude=self.manifest.PartialCloneExclude)
|
||||
clone_filter=project.manifest.CloneFilter,
|
||||
partial_clone_exclude=project.manifest.PartialCloneExclude)
|
||||
|
||||
output = buf.getvalue()
|
||||
if (opt.verbose or not success) and output:
|
||||
@ -471,13 +480,13 @@ later is required to fix a server side protocol bug.
|
||||
pm.end()
|
||||
self._fetch_times.Save()
|
||||
|
||||
if not self.manifest.IsArchive:
|
||||
if not self.outer_client.manifest.IsArchive:
|
||||
self._GCProjects(projects, opt, err_event)
|
||||
|
||||
return (ret, fetched)
|
||||
|
||||
def _FetchMain(self, opt, args, all_projects, err_event, manifest_name,
|
||||
load_local_manifests, ssh_proxy):
|
||||
load_local_manifests, ssh_proxy, manifest):
|
||||
"""The main network fetch loop.
|
||||
|
||||
Args:
|
||||
@ -488,11 +497,12 @@ later is required to fix a server side protocol bug.
|
||||
manifest_name: Manifest file to be reloaded.
|
||||
load_local_manifests: Whether to load local manifests.
|
||||
ssh_proxy: SSH manager for clients & masters.
|
||||
manifest: The manifest to use.
|
||||
|
||||
Returns:
|
||||
List of all projects that should be checked out.
|
||||
"""
|
||||
rp = self.manifest.repoProject
|
||||
rp = manifest.repoProject
|
||||
|
||||
to_fetch = []
|
||||
now = time.time()
|
||||
@ -516,7 +526,7 @@ later is required to fix a server side protocol bug.
|
||||
# Iteratively fetch missing and/or nested unregistered submodules
|
||||
previously_missing_set = set()
|
||||
while True:
|
||||
self._ReloadManifest(manifest_name, load_local_manifests)
|
||||
self._ReloadManifest(manifest_name, self.manifest, load_local_manifests)
|
||||
all_projects = self.GetProjects(args,
|
||||
missing_ok=True,
|
||||
submodules_ok=opt.fetch_submodules)
|
||||
@ -551,7 +561,7 @@ later is required to fix a server side protocol bug.
|
||||
Whether the fetch was successful.
|
||||
"""
|
||||
start = time.time()
|
||||
syncbuf = SyncBuffer(self.manifest.manifestProject.config,
|
||||
syncbuf = SyncBuffer(project.manifest.manifestProject.config,
|
||||
detach_head=detach_head)
|
||||
success = False
|
||||
try:
|
||||
@ -688,28 +698,29 @@ later is required to fix a server side protocol bug.
|
||||
t.join()
|
||||
pm.end()
|
||||
|
||||
def _ReloadManifest(self, manifest_name=None, load_local_manifests=True):
|
||||
def _ReloadManifest(self, manifest_name, manifest, load_local_manifests=True):
|
||||
"""Reload the manfiest from the file specified by the |manifest_name|.
|
||||
|
||||
It unloads the manifest if |manifest_name| is None.
|
||||
|
||||
Args:
|
||||
manifest_name: Manifest file to be reloaded.
|
||||
manifest: The manifest to use.
|
||||
load_local_manifests: Whether to load local manifests.
|
||||
"""
|
||||
if manifest_name:
|
||||
# Override calls Unload already
|
||||
self.manifest.Override(manifest_name, load_local_manifests=load_local_manifests)
|
||||
manifest.Override(manifest_name, load_local_manifests=load_local_manifests)
|
||||
else:
|
||||
self.manifest.Unload()
|
||||
manifest.Unload()
|
||||
|
||||
def UpdateProjectList(self, opt):
|
||||
def UpdateProjectList(self, opt, manifest):
|
||||
new_project_paths = []
|
||||
for project in self.GetProjects(None, missing_ok=True):
|
||||
if project.relpath:
|
||||
new_project_paths.append(project.relpath)
|
||||
file_name = 'project.list'
|
||||
file_path = os.path.join(self.manifest.subdir, file_name)
|
||||
file_path = os.path.join(manifest.subdir, file_name)
|
||||
old_project_paths = []
|
||||
|
||||
if os.path.exists(file_path):
|
||||
@ -721,16 +732,16 @@ later is required to fix a server side protocol bug.
|
||||
continue
|
||||
if path not in new_project_paths:
|
||||
# If the path has already been deleted, we don't need to do it
|
||||
gitdir = os.path.join(self.manifest.topdir, path, '.git')
|
||||
gitdir = os.path.join(manifest.topdir, path, '.git')
|
||||
if os.path.exists(gitdir):
|
||||
project = Project(
|
||||
manifest=self.manifest,
|
||||
manifest=manifest,
|
||||
name=path,
|
||||
remote=RemoteSpec('origin'),
|
||||
gitdir=gitdir,
|
||||
objdir=gitdir,
|
||||
use_git_worktrees=os.path.isfile(gitdir),
|
||||
worktree=os.path.join(self.manifest.topdir, path),
|
||||
worktree=os.path.join(manifest.topdir, path),
|
||||
relpath=path,
|
||||
revisionExpr='HEAD',
|
||||
revisionId=None,
|
||||
@ -746,7 +757,7 @@ later is required to fix a server side protocol bug.
|
||||
fd.write('\n')
|
||||
return 0
|
||||
|
||||
def UpdateCopyLinkfileList(self):
|
||||
def UpdateCopyLinkfileList(self, manifest):
|
||||
"""Save all dests of copyfile and linkfile, and update them if needed.
|
||||
|
||||
Returns:
|
||||
@ -765,7 +776,7 @@ later is required to fix a server side protocol bug.
|
||||
}
|
||||
|
||||
copylinkfile_name = 'copy-link-files.json'
|
||||
copylinkfile_path = os.path.join(self.manifest.subdir, copylinkfile_name)
|
||||
copylinkfile_path = os.path.join(manifest.subdir, copylinkfile_name)
|
||||
old_copylinkfile_paths = {}
|
||||
|
||||
if os.path.exists(copylinkfile_path):
|
||||
@ -796,13 +807,13 @@ later is required to fix a server side protocol bug.
|
||||
json.dump(new_paths, fp)
|
||||
return True
|
||||
|
||||
def _SmartSyncSetup(self, opt, smart_sync_manifest_path):
|
||||
if not self.manifest.manifest_server:
|
||||
def _SmartSyncSetup(self, opt, smart_sync_manifest_path, manifest):
|
||||
if not manifest.manifest_server:
|
||||
print('error: cannot smart sync: no manifest server defined in '
|
||||
'manifest', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
manifest_server = self.manifest.manifest_server
|
||||
manifest_server = manifest.manifest_server
|
||||
if not opt.quiet:
|
||||
print('Using manifest server %s' % manifest_server)
|
||||
|
||||
@ -843,7 +854,7 @@ later is required to fix a server side protocol bug.
|
||||
try:
|
||||
server = xmlrpc.client.Server(manifest_server, transport=transport)
|
||||
if opt.smart_sync:
|
||||
branch = self._GetBranch()
|
||||
branch = self._GetBranch(manifest.manifestProject)
|
||||
|
||||
if 'SYNC_TARGET' in os.environ:
|
||||
target = os.environ['SYNC_TARGET']
|
||||
@ -869,18 +880,18 @@ later is required to fix a server side protocol bug.
|
||||
% (smart_sync_manifest_path, e),
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
self._ReloadManifest(manifest_name)
|
||||
self._ReloadManifest(manifest_name, manifest)
|
||||
else:
|
||||
print('error: manifest server RPC call failed: %s' %
|
||||
manifest_str, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except (socket.error, IOError, xmlrpc.client.Fault) as e:
|
||||
print('error: cannot connect to manifest server %s:\n%s'
|
||||
% (self.manifest.manifest_server, e), file=sys.stderr)
|
||||
% (manifest.manifest_server, e), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
except xmlrpc.client.ProtocolError as e:
|
||||
print('error: cannot connect to manifest server %s:\n%d %s'
|
||||
% (self.manifest.manifest_server, e.errcode, e.errmsg),
|
||||
% (manifest.manifest_server, e.errcode, e.errmsg),
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
@ -891,14 +902,14 @@ later is required to fix a server side protocol bug.
|
||||
if not opt.local_only:
|
||||
start = time.time()
|
||||
success = mp.Sync_NetworkHalf(quiet=opt.quiet, verbose=opt.verbose,
|
||||
current_branch_only=self._GetCurrentBranchOnly(opt),
|
||||
current_branch_only=self._GetCurrentBranchOnly(opt, mp.manifest),
|
||||
force_sync=opt.force_sync,
|
||||
tags=opt.tags,
|
||||
optimized_fetch=opt.optimized_fetch,
|
||||
retry_fetches=opt.retry_fetches,
|
||||
submodules=self.manifest.HasSubmodules,
|
||||
clone_filter=self.manifest.CloneFilter,
|
||||
partial_clone_exclude=self.manifest.PartialCloneExclude)
|
||||
submodules=mp.manifest.HasSubmodules,
|
||||
clone_filter=mp.manifest.CloneFilter,
|
||||
partial_clone_exclude=mp.manifest.PartialCloneExclude)
|
||||
finish = time.time()
|
||||
self.event_log.AddSync(mp, event_log.TASK_SYNC_NETWORK,
|
||||
start, finish, success)
|
||||
@ -906,15 +917,15 @@ later is required to fix a server side protocol bug.
|
||||
if mp.HasChanges:
|
||||
syncbuf = SyncBuffer(mp.config)
|
||||
start = time.time()
|
||||
mp.Sync_LocalHalf(syncbuf, submodules=self.manifest.HasSubmodules)
|
||||
mp.Sync_LocalHalf(syncbuf, submodules=mp.manifest.HasSubmodules)
|
||||
clean = syncbuf.Finish()
|
||||
self.event_log.AddSync(mp, event_log.TASK_SYNC_LOCAL,
|
||||
start, time.time(), clean)
|
||||
if not clean:
|
||||
sys.exit(1)
|
||||
self._ReloadManifest(manifest_name)
|
||||
self._ReloadManifest(manifest_name, mp.manifest)
|
||||
if opt.jobs is None:
|
||||
self.jobs = self.manifest.default.sync_j
|
||||
self.jobs = mp.manifest.default.sync_j
|
||||
|
||||
def ValidateOptions(self, opt, args):
|
||||
if opt.force_broken:
|
||||
@ -937,7 +948,7 @@ later is required to fix a server side protocol bug.
|
||||
if opt.prune is None:
|
||||
opt.prune = True
|
||||
|
||||
if self.manifest.is_multimanifest and not opt.this_manifest_only and args:
|
||||
if self.outer_client.manifest.is_multimanifest and not opt.this_manifest_only and args:
|
||||
self.OptionParser.error('partial syncs must use --this-manifest-only')
|
||||
|
||||
def Execute(self, opt, args):
|
||||
@ -947,18 +958,22 @@ later is required to fix a server side protocol bug.
|
||||
soft_limit, _ = _rlimit_nofile()
|
||||
self.jobs = min(self.jobs, (soft_limit - 5) // 3)
|
||||
|
||||
manifest = self.outer_manifest
|
||||
if opt.this_manifest_only or not opt.outer_manifest:
|
||||
manifest = self.manifest
|
||||
|
||||
if opt.manifest_name:
|
||||
self.manifest.Override(opt.manifest_name)
|
||||
manifest.Override(opt.manifest_name)
|
||||
|
||||
manifest_name = opt.manifest_name
|
||||
smart_sync_manifest_path = os.path.join(
|
||||
self.manifest.manifestProject.worktree, 'smart_sync_override.xml')
|
||||
manifest.manifestProject.worktree, 'smart_sync_override.xml')
|
||||
|
||||
if opt.clone_bundle is None:
|
||||
opt.clone_bundle = self.manifest.CloneBundle
|
||||
opt.clone_bundle = manifest.CloneBundle
|
||||
|
||||
if opt.smart_sync or opt.smart_tag:
|
||||
manifest_name = self._SmartSyncSetup(opt, smart_sync_manifest_path)
|
||||
manifest_name = self._SmartSyncSetup(opt, smart_sync_manifest_path, manifest)
|
||||
else:
|
||||
if os.path.isfile(smart_sync_manifest_path):
|
||||
try:
|
||||
@ -969,7 +984,7 @@ later is required to fix a server side protocol bug.
|
||||
|
||||
err_event = multiprocessing.Event()
|
||||
|
||||
rp = self.manifest.repoProject
|
||||
rp = manifest.repoProject
|
||||
rp.PreSync()
|
||||
cb = rp.CurrentBranch
|
||||
if cb:
|
||||
@ -979,34 +994,35 @@ later is required to fix a server side protocol bug.
|
||||
'receive updates; run `repo init --repo-rev=stable` to fix.',
|
||||
file=sys.stderr)
|
||||
|
||||
mp = self.manifest.manifestProject
|
||||
mp = manifest.manifestProject
|
||||
is_standalone_manifest = bool(mp.standalone_manifest_url)
|
||||
if not is_standalone_manifest:
|
||||
mp.PreSync()
|
||||
|
||||
if opt.repo_upgraded:
|
||||
_PostRepoUpgrade(self.manifest, quiet=opt.quiet)
|
||||
_PostRepoUpgrade(manifest, quiet=opt.quiet)
|
||||
|
||||
if not opt.mp_update:
|
||||
print('Skipping update of local manifest project.')
|
||||
elif not is_standalone_manifest:
|
||||
self._UpdateManifestProject(opt, mp, manifest_name)
|
||||
|
||||
load_local_manifests = not self.manifest.HasLocalManifests
|
||||
use_superproject = git_superproject.UseSuperproject(opt, self.manifest)
|
||||
if use_superproject and (self.manifest.IsMirror or self.manifest.IsArchive):
|
||||
load_local_manifests = not manifest.HasLocalManifests
|
||||
use_superproject = git_superproject.UseSuperproject(opt.use_superproject, manifest)
|
||||
if use_superproject and (manifest.IsMirror or manifest.IsArchive):
|
||||
# Don't use superproject, because we have no working tree.
|
||||
use_superproject = False
|
||||
if opt.use_superproject is not None:
|
||||
print('Defaulting to no-use-superproject because there is no working tree.')
|
||||
superproject_logging_data = {
|
||||
'superproject': use_superproject,
|
||||
'haslocalmanifests': bool(self.manifest.HasLocalManifests),
|
||||
'hassuperprojecttag': bool(self.manifest.superproject),
|
||||
'haslocalmanifests': bool(manifest.HasLocalManifests),
|
||||
'hassuperprojecttag': bool(manifest.superproject),
|
||||
}
|
||||
if use_superproject:
|
||||
manifest_name = self._UpdateProjectsRevisionId(
|
||||
opt, args, load_local_manifests, superproject_logging_data) or opt.manifest_name
|
||||
opt, args, load_local_manifests, superproject_logging_data,
|
||||
manifest) or opt.manifest_name
|
||||
|
||||
if self.gitc_manifest:
|
||||
gitc_manifest_projects = self.GetProjects(args,
|
||||
@ -1029,7 +1045,7 @@ later is required to fix a server side protocol bug.
|
||||
if manifest_name:
|
||||
manifest.Override(manifest_name)
|
||||
else:
|
||||
manifest.Override(self.manifest.manifestFile)
|
||||
manifest.Override(manifest.manifestFile)
|
||||
gitc_utils.generate_gitc_manifest(self.gitc_manifest,
|
||||
manifest,
|
||||
gitc_projects)
|
||||
@ -1039,7 +1055,7 @@ later is required to fix a server side protocol bug.
|
||||
# generate a new args list to represent the opened projects.
|
||||
# TODO: make this more reliable -- if there's a project name/path overlap,
|
||||
# this may choose the wrong project.
|
||||
args = [os.path.relpath(self.manifest.paths[path].worktree, os.getcwd())
|
||||
args = [os.path.relpath(manifest.paths[path].worktree, os.getcwd())
|
||||
for path in opened_projects]
|
||||
if not args:
|
||||
return
|
||||
@ -1050,7 +1066,7 @@ later is required to fix a server side protocol bug.
|
||||
err_network_sync = False
|
||||
err_update_projects = False
|
||||
|
||||
self._fetch_times = _FetchTimes(self.manifest)
|
||||
self._fetch_times = _FetchTimes(manifest)
|
||||
if not opt.local_only:
|
||||
with multiprocessing.Manager() as manager:
|
||||
with ssh.ProxyManager(manager) as ssh_proxy:
|
||||
@ -1058,7 +1074,7 @@ later is required to fix a server side protocol bug.
|
||||
ssh_proxy.sock()
|
||||
all_projects = self._FetchMain(opt, args, all_projects, err_event,
|
||||
manifest_name, load_local_manifests,
|
||||
ssh_proxy)
|
||||
ssh_proxy, manifest)
|
||||
|
||||
if opt.network_only:
|
||||
return
|
||||
@ -1074,18 +1090,18 @@ later is required to fix a server side protocol bug.
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if self.manifest.IsMirror or self.manifest.IsArchive:
|
||||
if manifest.IsMirror or manifest.IsArchive:
|
||||
# bail out now, we have no working tree
|
||||
return
|
||||
|
||||
if self.UpdateProjectList(opt):
|
||||
if self.UpdateProjectList(opt, manifest):
|
||||
err_event.set()
|
||||
err_update_projects = True
|
||||
if opt.fail_fast:
|
||||
print('\nerror: Local checkouts *not* updated.', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
err_update_linkfiles = not self.UpdateCopyLinkfileList()
|
||||
err_update_linkfiles = not self.UpdateCopyLinkfileList(manifest)
|
||||
if err_update_linkfiles:
|
||||
err_event.set()
|
||||
if opt.fail_fast:
|
||||
@ -1100,8 +1116,8 @@ later is required to fix a server side protocol bug.
|
||||
|
||||
# If there's a notice that's supposed to print at the end of the sync, print
|
||||
# it now...
|
||||
if self.manifest.notice:
|
||||
print(self.manifest.notice)
|
||||
if manifest.notice:
|
||||
print(manifest.notice)
|
||||
|
||||
# If we saw an error, exit with code 1 so that other scripts can check.
|
||||
if err_event.is_set():
|
||||
|
@ -42,4 +42,4 @@ def test_get_current_branch_only(use_superproject, cli_args, result):
|
||||
opts, _ = cmd.OptionParser.parse_args(cli_args)
|
||||
|
||||
with mock.patch('git_superproject.UseSuperproject', return_value=use_superproject):
|
||||
assert cmd._GetCurrentBranchOnly(opts) == result
|
||||
assert cmd._GetCurrentBranchOnly(opts, cmd.manifest) == result
|
||||
|
Reference in New Issue
Block a user