# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import collections
import functools
import http.cookiejar as cookielib
import io
import json
import multiprocessing
import netrc
from optparse import SUPPRESS_HELP
import os
import socket
import sys
import tempfile
import time
from typing import NamedTuple, List, Set
import urllib.error
import urllib.parse
import urllib.request
import xml.parsers.expat
import xmlrpc.client

try:
    import threading as _threading
except ImportError:
    import dummy_threading as _threading

try:
    import resource

    def _rlimit_nofile():
        return resource.getrlimit(resource.RLIMIT_NOFILE)

except ImportError:

    def _rlimit_nofile():
        return (256, 256)


import event_log
from git_command import git_require
from git_config import GetUrlCookieFile
from git_refs import R_HEADS, HEAD
import git_superproject
import gitc_utils
from project import Project
from project import RemoteSpec
from command import (
    Command,
    DEFAULT_LOCAL_JOBS,
    MirrorSafeCommand,
    WORKER_BATCH_SIZE,
)
from error import RepoChangedException, GitError
import platform_utils
from project import SyncBuffer
from progress import Progress, elapsed_str, jobs_str
from repo_trace import Trace
import ssh
from wrapper import Wrapper
from manifest_xml import GitcManifest

_ONE_DAY_S = 24 * 60 * 60

# Env var to implicitly turn auto-gc back on.  This was added to allow a user to
# revert a change in default behavior in v2.29.9.  Remove after 2023-04-01.
_REPO_AUTO_GC = "REPO_AUTO_GC"
_AUTO_GC = os.environ.get(_REPO_AUTO_GC) == "1"


class _FetchOneResult(NamedTuple):
    """_FetchOne return value.

    Attributes:
      success (bool): True if successful.
      project (Project): The fetched project.
      start (float): The starting time.time().
      finish (float): The ending time.time().
      remote_fetched (bool): True if the remote was actually queried.
    """

    success: bool
    project: Project
    start: float
    finish: float
    remote_fetched: bool


class _FetchResult(NamedTuple):
    """_Fetch return value.

    Attributes:
      success (bool): True if successful.
      projects (Set[str]): The names of the git directories of fetched projects.
    """

    success: bool
    projects: Set[str]


class _FetchMainResult(NamedTuple):
    """_FetchMain return value.

    Attributes:
      all_projects (List[Project]): The fetched projects.
    """

    all_projects: List[Project]


class _CheckoutOneResult(NamedTuple):
    """_CheckoutOne return value.

    Attributes:
      success (bool): True if successful.
      project (Project): The project.
      start (float): The starting time.time().
      finish (float): The ending time.time().
    """

    success: bool
    project: Project
    start: float
    finish: float


class Sync(Command, MirrorSafeCommand):
    COMMON = True
    MULTI_MANIFEST_SUPPORT = True
    helpSummary = "Update working tree to the latest revision"
    helpUsage = """
%prog [<project>...]
"""
    helpDescription = """
The '%prog' command synchronizes local project directories
with the remote repositories specified in the manifest.  If a local
project does not yet exist, it will clone a new local directory from
the remote repository and set up tracking branches as specified in
the manifest.  If the local project already exists, '%prog'
will update the remote branches and rebase any new local changes
on top of the new remote changes.

'%prog' will synchronize all projects listed at the command
line.  Projects can be specified either by name, or by a relative
or absolute path to the project's local directory. If no projects
are specified, '%prog' will synchronize all projects listed in
the manifest.

The -d/--detach option can be used to switch specified projects
back to the manifest revision.  This option is especially helpful
if the project is currently on a topic branch, but the manifest
revision is temporarily needed.

The -s/--smart-sync option can be used to sync to a known good
build as specified by the manifest-server element in the current
manifest. The -t/--smart-tag option is similar and allows you to
specify a custom tag/label.

The -u/--manifest-server-username and -p/--manifest-server-password
options can be used to specify a username and password to authenticate
with the manifest server when using the -s or -t option.

If -u and -p are not specified when using the -s or -t option, '%prog'
will attempt to read authentication credentials for the manifest server
from the user's .netrc file.

'%prog' will not use authentication credentials from -u/-p or .netrc
if the manifest server specified in the manifest file already includes
credentials.

By default, all projects will be synced. The --fail-fast option can be used
to halt syncing as soon as possible when the first project fails to sync.

The --force-sync option can be used to overwrite existing git
directories if they have previously been linked to a different
object directory. WARNING: This may cause data to be lost since
refs may be removed when overwriting.

The --force-remove-dirty option can be used to remove previously used
projects with uncommitted changes. WARNING: This may cause data to be
lost since uncommitted changes may be removed with projects that no longer
exist in the manifest.

The --no-clone-bundle option disables any attempt to use
$URL/clone.bundle to bootstrap a new Git repository from a
resumeable bundle file on a content delivery network. This
may be necessary if there are problems with the local Python
HTTP client or proxy configuration, but the Git binary works.

The --fetch-submodules option enables fetching Git submodules
of a project from server.

The -c/--current-branch option can be used to only fetch objects that
are on the branch specified by a project's revision.

The --optimized-fetch option can be used to only fetch projects that
are fixed to a sha1 revision if the sha1 revision does not already
exist locally.

The --prune option can be used to remove any refs that no longer
exist on the remote.

The --auto-gc option can be used to trigger garbage collection on all
projects. By default, repo does not run garbage collection.

# SSH Connections

If at least one project remote URL uses an SSH connection (ssh://,
git+ssh://, or user@host:path syntax) repo will automatically
enable the SSH ControlMaster option when connecting to that host.
This feature permits other projects in the same '%prog' session to
reuse the same SSH tunnel, saving connection setup overheads.

To disable this behavior on UNIX platforms, set the GIT_SSH
environment variable to 'ssh'.  For example:

  export GIT_SSH=ssh
  %prog

# Compatibility

This feature is automatically disabled on Windows, due to the lack
of UNIX domain socket support.

This feature is not compatible with url.insteadof rewrites in the
user's ~/.gitconfig.  '%prog' is currently not able to perform the
rewrite early enough to establish the ControlMaster tunnel.

If the remote SSH daemon is Gerrit Code Review, version 2.0.10 or
later is required to fix a server side protocol bug.

"""
    # A value of 0 means we want parallel jobs, but we'll determine the default
    # value later on.
    PARALLEL_JOBS = 0

    def _Options(self, p, show_smart=True):
        p.add_option(
            "--jobs-network",
            default=None,
            type=int,
            metavar="JOBS",
            help="number of network jobs to run in parallel (defaults to "
            "--jobs or 1)",
        )
        p.add_option(
            "--jobs-checkout",
            default=None,
            type=int,
            metavar="JOBS",
            help="number of local checkout jobs to run in parallel (defaults "
            f"to --jobs or {DEFAULT_LOCAL_JOBS})",
        )

        p.add_option(
            "-f",
            "--force-broken",
            dest="force_broken",
            action="store_true",
            help="obsolete option (to be deleted in the future)",
        )
        p.add_option(
            "--fail-fast",
            dest="fail_fast",
            action="store_true",
            help="stop syncing after first error is hit",
        )
        p.add_option(
            "--force-sync",
            dest="force_sync",
            action="store_true",
            help="overwrite an existing git directory if it needs to "
            "point to a different object directory. WARNING: this "
            "may cause loss of data",
        )
        p.add_option(
            "--force-remove-dirty",
            dest="force_remove_dirty",
            action="store_true",
            help="force remove projects with uncommitted modifications if "
            "projects no longer exist in the manifest. "
            "WARNING: this may cause loss of data",
        )
        p.add_option(
            "-l",
            "--local-only",
            dest="local_only",
            action="store_true",
            help="only update working tree, don't fetch",
        )
        p.add_option(
            "--no-manifest-update",
            "--nmu",
            dest="mp_update",
            action="store_false",
            default="true",
            help="use the existing manifest checkout as-is. "
            "(do not update to the latest revision)",
        )
        p.add_option(
            "-n",
            "--network-only",
            dest="network_only",
            action="store_true",
            help="fetch only, don't update working tree",
        )
        p.add_option(
            "-d",
            "--detach",
            dest="detach_head",
            action="store_true",
            help="detach projects back to manifest revision",
        )
        p.add_option(
            "-c",
            "--current-branch",
            dest="current_branch_only",
            action="store_true",
            help="fetch only current branch from server",
        )
        p.add_option(
            "--no-current-branch",
            dest="current_branch_only",
            action="store_false",
            help="fetch all branches from server",
        )
        p.add_option(
            "-m",
            "--manifest-name",
            dest="manifest_name",
            help="temporary manifest to use for this sync",
            metavar="NAME.xml",
        )
        p.add_option(
            "--clone-bundle",
            action="store_true",
            help="enable use of /clone.bundle on HTTP/HTTPS",
        )
        p.add_option(
            "--no-clone-bundle",
            dest="clone_bundle",
            action="store_false",
            help="disable use of /clone.bundle on HTTP/HTTPS",
        )
        p.add_option(
            "-u",
            "--manifest-server-username",
            action="store",
            dest="manifest_server_username",
            help="username to authenticate with the manifest server",
        )
        p.add_option(
            "-p",
            "--manifest-server-password",
            action="store",
            dest="manifest_server_password",
            help="password to authenticate with the manifest server",
        )
        p.add_option(
            "--fetch-submodules",
            dest="fetch_submodules",
            action="store_true",
            help="fetch submodules from server",
        )
        p.add_option(
            "--use-superproject",
            action="store_true",
            help="use the manifest superproject to sync projects; implies -c",
        )
        p.add_option(
            "--no-use-superproject",
            action="store_false",
            dest="use_superproject",
            help="disable use of manifest superprojects",
        )
        p.add_option("--tags", action="store_true", help="fetch tags")
        p.add_option(
            "--no-tags",
            dest="tags",
            action="store_false",
            help="don't fetch tags (default)",
        )
        p.add_option(
            "--optimized-fetch",
            dest="optimized_fetch",
            action="store_true",
            help="only fetch projects fixed to sha1 if revision does not exist "
            "locally",
        )
        p.add_option(
            "--retry-fetches",
            default=0,
            action="store",
            type="int",
            help="number of times to retry fetches on transient errors",
        )
        p.add_option(
            "--prune",
            action="store_true",
            help="delete refs that no longer exist on the remote (default)",
        )
        p.add_option(
            "--no-prune",
            dest="prune",
            action="store_false",
            help="do not delete refs that no longer exist on the remote",
        )
        p.add_option(
            "--auto-gc",
            action="store_true",
            default=None,
            help="run garbage collection on all synced projects",
        )
        p.add_option(
            "--no-auto-gc",
            dest="auto_gc",
            action="store_false",
            help="do not run garbage collection on any projects (default)",
        )
        if show_smart:
            p.add_option(
                "-s",
                "--smart-sync",
                dest="smart_sync",
                action="store_true",
                help="smart sync using manifest from the latest known good "
                "build",
            )
            p.add_option(
                "-t",
                "--smart-tag",
                dest="smart_tag",
                action="store",
                help="smart sync using manifest from a known tag",
            )

        g = p.add_option_group("repo Version options")
        g.add_option(
            "--no-repo-verify",
            dest="repo_verify",
            default=True,
            action="store_false",
            help="do not verify repo source code",
        )
        g.add_option(
            "--repo-upgraded",
            dest="repo_upgraded",
            action="store_true",
            help=SUPPRESS_HELP,
        )

    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, 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.use_superproject, manifest)
            or opt.current_branch_only
        )

    def _UpdateProjectsRevisionId(
        self, opt, args, superproject_logging_data, manifest
    ):
        """Update revisionId of projects with the commit from the superproject.

        This function updates each project's revisionId with the commit hash
        from the superproject.  It writes the updated manifest into a file and
        reloads the manifest from it.  When appropriate, sub manifests are also
        processed.

        Args:
            opt: Program options returned from optparse.  See _Options().
            args: Arguments to pass to GetProjects. See the GetProjects
                docstring for details.
            superproject_logging_data: A dictionary of superproject data to log.
            manifest: The manifest to use.
        """
        have_superproject = manifest.superproject or any(
            m.superproject for m in manifest.all_children
        )
        if not have_superproject:
            return

        if opt.local_only and manifest.superproject:
            manifest_path = manifest.superproject.manifest_path
            if manifest_path:
                self._ReloadManifest(manifest_path, manifest)
            return

        all_projects = self.GetProjects(
            args,
            missing_ok=True,
            submodules_ok=opt.fetch_submodules,
            manifest=manifest,
            all_manifests=not opt.this_manifest_only,
        )

        per_manifest = collections.defaultdict(list)
        if opt.this_manifest_only:
            per_manifest[manifest.path_prefix] = all_projects
        else:
            for p in all_projects:
                per_manifest[p.manifest.path_prefix].append(p)

        superproject_logging_data = {}
        need_unload = False
        for m in self.ManifestList(opt):
            if m.path_prefix not in per_manifest:
                continue
            use_super = git_superproject.UseSuperproject(
                opt.use_superproject, m
            )
            if superproject_logging_data:
                superproject_logging_data["multimanifest"] = True
            superproject_logging_data.update(
                superproject=use_super,
                haslocalmanifests=bool(m.HasLocalManifests),
                hassuperprojecttag=bool(m.superproject),
            )
            if use_super and (m.IsMirror or m.IsArchive):
                # Don't use superproject, because we have no working tree.
                use_super = False
                superproject_logging_data["superproject"] = False
                superproject_logging_data["noworktree"] = True
                if opt.use_superproject is not False:
                    print(
                        f"{m.path_prefix}: not using superproject because "
                        "there is no working tree."
                    )

            if not use_super:
                continue
            m.superproject.SetQuiet(opt.quiet)
            print_messages = git_superproject.PrintMessages(
                opt.use_superproject, m
            )
            m.superproject.SetPrintMessages(print_messages)
            update_result = m.superproject.UpdateProjectsRevisionId(
                per_manifest[m.path_prefix], git_event_log=self.git_event_log
            )
            manifest_path = update_result.manifest_path
            superproject_logging_data["updatedrevisionid"] = bool(manifest_path)
            if manifest_path:
                m.SetManifestOverride(manifest_path)
                need_unload = True
            else:
                if print_messages:
                    print(
                        f"{m.path_prefix}: warning: Update of revisionId from "
                        "superproject has failed, repo sync will not use "
                        "superproject to fetch the source. ",
                        "Please resync with the --no-use-superproject option "
                        "to avoid this repo warning.",
                        file=sys.stderr,
                    )
                if update_result.fatal and opt.use_superproject is not None:
                    sys.exit(1)
        if need_unload:
            m.outer_client.manifest.Unload()

    def _FetchProjectList(self, opt, projects):
        """Main function of the fetch worker.

        The projects we're given share the same underlying git object store, so
        we have to fetch them in serial.

        Delegates most of the work to _FetchOne.

        Args:
            opt: Program options returned from optparse.  See _Options().
            projects: Projects to fetch.
        """
        return [self._FetchOne(opt, x) for x in projects]

    def _FetchOne(self, opt, project):
        """Fetch git objects for a single project.

        Args:
            opt: Program options returned from optparse.  See _Options().
            project: Project object for the project to fetch.

        Returns:
            Whether the fetch was successful.
        """
        start = time.time()
        k = f"{project.name} @ {project.relpath}"
        self._sync_dict[k] = start
        success = False
        remote_fetched = False
        buf = io.StringIO()
        try:
            sync_result = project.Sync_NetworkHalf(
                quiet=opt.quiet,
                verbose=opt.verbose,
                output_redir=buf,
                current_branch_only=self._GetCurrentBranchOnly(
                    opt, project.manifest
                ),
                force_sync=opt.force_sync,
                clone_bundle=opt.clone_bundle,
                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=project.manifest.CloneFilter,
                partial_clone_exclude=project.manifest.PartialCloneExclude,
            )
            success = sync_result.success
            remote_fetched = sync_result.remote_fetched

            output = buf.getvalue()
            if (opt.verbose or not success) and output:
                print("\n" + output.rstrip())

            if not success:
                print(
                    "error: Cannot fetch %s from %s"
                    % (project.name, project.remote.url),
                    file=sys.stderr,
                )
        except KeyboardInterrupt:
            print(f"Keyboard interrupt while processing {project.name}")
        except GitError as e:
            print("error.GitError: Cannot fetch %s" % str(e), file=sys.stderr)
        except Exception as e:
            print(
                "error: Cannot fetch %s (%s: %s)"
                % (project.name, type(e).__name__, str(e)),
                file=sys.stderr,
            )
            del self._sync_dict[k]
            raise

        finish = time.time()
        del self._sync_dict[k]
        return _FetchOneResult(success, project, start, finish, remote_fetched)

    @classmethod
    def _FetchInitChild(cls, ssh_proxy):
        cls.ssh_proxy = ssh_proxy

    def _GetSyncProgressMessage(self):
        if len(self._sync_dict) == 0:
            return None

        earliest_time = float("inf")
        earliest_proj = None
        for project, t in self._sync_dict.items():
            if t < earliest_time:
                earliest_time = t
                earliest_proj = project

        elapsed = time.time() - earliest_time
        jobs = jobs_str(len(self._sync_dict))
        return f"{jobs} | {elapsed_str(elapsed)} {earliest_proj}"

    def _Fetch(self, projects, opt, err_event, ssh_proxy):
        ret = True

        jobs = opt.jobs_network
        fetched = set()
        remote_fetched = set()
        pm = Progress(
            "Fetching",
            len(projects),
            delay=False,
            quiet=opt.quiet,
            show_elapsed=True,
            elide=True,
        )

        self._sync_dict = multiprocessing.Manager().dict()
        sync_event = _threading.Event()

        def _MonitorSyncLoop():
            while True:
                pm.update(inc=0, msg=self._GetSyncProgressMessage())
                if sync_event.wait(timeout=1):
                    return

        sync_progress_thread = _threading.Thread(target=_MonitorSyncLoop)
        sync_progress_thread.daemon = True
        sync_progress_thread.start()

        objdir_project_map = dict()
        for project in projects:
            objdir_project_map.setdefault(project.objdir, []).append(project)
        projects_list = list(objdir_project_map.values())

        def _ProcessResults(results_sets):
            ret = True
            for results in results_sets:
                for result in results:
                    success = result.success
                    project = result.project
                    start = result.start
                    finish = result.finish
                    self._fetch_times.Set(project, finish - start)
                    self.event_log.AddSync(
                        project,
                        event_log.TASK_SYNC_NETWORK,
                        start,
                        finish,
                        success,
                    )
                    if result.remote_fetched:
                        remote_fetched.add(project)
                    # Check for any errors before running any more tasks.
                    # ...we'll let existing jobs finish, though.
                    if not success:
                        ret = False
                    else:
                        fetched.add(project.gitdir)
                    pm.update()
                if not ret and opt.fail_fast:
                    break
            return ret

        # We pass the ssh proxy settings via the class.  This allows
        # multiprocessing to pickle it up when spawning children.  We can't pass
        # it as an argument to _FetchProjectList below as multiprocessing is
        # unable to pickle those.
        Sync.ssh_proxy = None

        # NB: Multiprocessing is heavy, so don't spin it up for one job.
        if len(projects_list) == 1 or jobs == 1:
            self._FetchInitChild(ssh_proxy)
            if not _ProcessResults(
                self._FetchProjectList(opt, x) for x in projects_list
            ):
                ret = False
        else:
            # Favor throughput over responsiveness when quiet.  It seems that
            # imap() will yield results in batches relative to chunksize, so
            # even as the children finish a sync, we won't see the result until
            # one child finishes ~chunksize jobs.  When using a large --jobs
            # with large chunksize, this can be jarring as there will be a large
            # initial delay where repo looks like it isn't doing anything and
            # sits at 0%, but then suddenly completes a lot of jobs all at once.
            # Since this code is more network bound, we can accept a bit more
            # CPU overhead with a smaller chunksize so that the user sees more
            # immediate & continuous feedback.
            if opt.quiet:
                chunksize = WORKER_BATCH_SIZE
            else:
                pm.update(inc=0, msg="warming up")
                chunksize = 4
            with multiprocessing.Pool(
                jobs, initializer=self._FetchInitChild, initargs=(ssh_proxy,)
            ) as pool:
                results = pool.imap_unordered(
                    functools.partial(self._FetchProjectList, opt),
                    projects_list,
                    chunksize=chunksize,
                )
                if not _ProcessResults(results):
                    ret = False
                    pool.close()

        # Cleanup the reference now that we're done with it, and we're going to
        # release any resources it points to.  If we don't, later
        # multiprocessing usage (e.g. checkouts) will try to pickle and then
        # crash.
        del Sync.ssh_proxy

        sync_event.set()
        pm.end()
        self._fetch_times.Save()

        if not self.outer_client.manifest.IsArchive:
            self._GCProjects(projects, opt, err_event)

        return _FetchResult(ret, fetched)

    def _FetchMain(
        self, opt, args, all_projects, err_event, ssh_proxy, manifest
    ):
        """The main network fetch loop.

        Args:
            opt: Program options returned from optparse.  See _Options().
            args: Command line args used to filter out projects.
            all_projects: List of all projects that should be fetched.
            err_event: Whether an error was hit while processing.
            ssh_proxy: SSH manager for clients & masters.
            manifest: The manifest to use.

        Returns:
            List of all projects that should be checked out.
        """
        rp = manifest.repoProject

        to_fetch = []
        now = time.time()
        if _ONE_DAY_S <= (now - rp.LastFetch):
            to_fetch.append(rp)
        to_fetch.extend(all_projects)
        to_fetch.sort(key=self._fetch_times.Get, reverse=True)

        result = self._Fetch(to_fetch, opt, err_event, ssh_proxy)
        success = result.success
        fetched = result.projects
        if not success:
            err_event.set()

        _PostRepoFetch(rp, opt.repo_verify)
        if opt.network_only:
            # Bail out now; the rest touches the working tree.
            if err_event.is_set():
                print(
                    "\nerror: Exited sync due to fetch errors.\n",
                    file=sys.stderr,
                )
                sys.exit(1)
            return _FetchMainResult([])

        # Iteratively fetch missing and/or nested unregistered submodules.
        previously_missing_set = set()
        while True:
            self._ReloadManifest(None, manifest)
            all_projects = self.GetProjects(
                args,
                missing_ok=True,
                submodules_ok=opt.fetch_submodules,
                manifest=manifest,
                all_manifests=not opt.this_manifest_only,
            )
            missing = []
            for project in all_projects:
                if project.gitdir not in fetched:
                    missing.append(project)
            if not missing:
                break
            # Stop us from non-stopped fetching actually-missing repos: If set
            # of missing repos has not been changed from last fetch, we break.
            missing_set = set(p.name for p in missing)
            if previously_missing_set == missing_set:
                break
            previously_missing_set = missing_set
            result = self._Fetch(missing, opt, err_event, ssh_proxy)
            success = result.success
            new_fetched = result.projects
            if not success:
                err_event.set()
            fetched.update(new_fetched)

        return _FetchMainResult(all_projects)

    def _CheckoutOne(self, detach_head, force_sync, project):
        """Checkout work tree for one project

        Args:
            detach_head: Whether to leave a detached HEAD.
            force_sync: Force checking out of the repo.
            project: Project object for the project to checkout.

        Returns:
            Whether the fetch was successful.
        """
        start = time.time()
        syncbuf = SyncBuffer(
            project.manifest.manifestProject.config, detach_head=detach_head
        )
        success = False
        try:
            project.Sync_LocalHalf(syncbuf, force_sync=force_sync)
            success = syncbuf.Finish()
        except GitError as e:
            print(
                "error.GitError: Cannot checkout %s: %s"
                % (project.name, str(e)),
                file=sys.stderr,
            )
        except Exception as e:
            print(
                "error: Cannot checkout %s: %s: %s"
                % (project.name, type(e).__name__, str(e)),
                file=sys.stderr,
            )
            raise

        if not success:
            print("error: Cannot checkout %s" % (project.name), file=sys.stderr)
        finish = time.time()
        return _CheckoutOneResult(success, project, start, finish)

    def _Checkout(self, all_projects, opt, err_results):
        """Checkout projects listed in all_projects

        Args:
            all_projects: List of all projects that should be checked out.
            opt: Program options returned from optparse.  See _Options().
            err_results: A list of strings, paths to git repos where checkout
                failed.
        """
        # Only checkout projects with worktrees.
        all_projects = [x for x in all_projects if x.worktree]

        def _ProcessResults(pool, pm, results):
            ret = True
            for result in results:
                success = result.success
                project = result.project
                start = result.start
                finish = result.finish
                self.event_log.AddSync(
                    project, event_log.TASK_SYNC_LOCAL, start, finish, success
                )
                # Check for any errors before running any more tasks.
                # ...we'll let existing jobs finish, though.
                if not success:
                    ret = False
                    err_results.append(
                        project.RelPath(local=opt.this_manifest_only)
                    )
                    if opt.fail_fast:
                        if pool:
                            pool.close()
                        return ret
                pm.update(msg=project.name)
            return ret

        return (
            self.ExecuteInParallel(
                opt.jobs_checkout,
                functools.partial(
                    self._CheckoutOne, opt.detach_head, opt.force_sync
                ),
                all_projects,
                callback=_ProcessResults,
                output=Progress(
                    "Checking out", len(all_projects), quiet=opt.quiet
                ),
            )
            and not err_results
        )

    @staticmethod
    def _GetPreciousObjectsState(project: Project, opt):
        """Get the preciousObjects state for the project.

        Args:
            project (Project): the project to examine, and possibly correct.
            opt (optparse.Values): options given to sync.

        Returns:
            Expected state of extensions.preciousObjects:
                False: Should be disabled. (not present)
                True: Should be enabled.
        """
        if project.use_git_worktrees:
            return False
        projects = project.manifest.GetProjectsWithName(
            project.name, all_manifests=True
        )
        if len(projects) == 1:
            return False
        if len(projects) > 1:
            # Objects are potentially shared with another project.
            # See the logic in Project.Sync_NetworkHalf regarding UseAlternates.
            # - When False, shared projects share (via symlink)
            #   .repo/project-objects/{PROJECT_NAME}.git as the one-and-only
            #   objects directory.  All objects are precious, since there is no
            #   project with a complete set of refs.
            # - When True, shared projects share (via info/alternates)
            #   .repo/project-objects/{PROJECT_NAME}.git as an alternate object
            #   store, which is written only on the first clone of the project,
            #   and is not written subsequently. (When Sync_NetworkHalf sees
            #   that it exists, it makes sure that the alternates file points
            #   there, and uses a project-local .git/objects directory for all
            #   syncs going forward.
            # We do not support switching between the options.  The environment
            # variable is present for testing and migration only.
            return not project.UseAlternates

        return False

    def _SetPreciousObjectsState(self, project: Project, opt):
        """Correct the preciousObjects state for the project.

        Args:
            project: the project to examine, and possibly correct.
            opt: options given to sync.
        """
        expected = self._GetPreciousObjectsState(project, opt)
        actual = (
            project.config.GetBoolean("extensions.preciousObjects") or False
        )
        relpath = project.RelPath(local=opt.this_manifest_only)

        if expected != actual:
            # If this is unexpected, log it and repair.
            Trace(
                f"{relpath} expected preciousObjects={expected}, got {actual}"
            )
            if expected:
                if not opt.quiet:
                    print(
                        "\r%s: Shared project %s found, disabling pruning."
                        % (relpath, project.name)
                    )
                if git_require((2, 7, 0)):
                    project.EnableRepositoryExtension("preciousObjects")
                else:
                    # This isn't perfect, but it's the best we can do with old
                    # git.
                    print(
                        "\r%s: WARNING: shared projects are unreliable when "
                        "using old versions of git; please upgrade to "
                        "git-2.7.0+." % (relpath,),
                        file=sys.stderr,
                    )
                    project.config.SetString("gc.pruneExpire", "never")
            else:
                if not opt.quiet:
                    print(f"\r{relpath}: not shared, disabling pruning.")
                project.config.SetString("extensions.preciousObjects", None)
                project.config.SetString("gc.pruneExpire", None)

    def _GCProjects(self, projects, opt, err_event):
        """Perform garbage collection.

        If We are skipping garbage collection (opt.auto_gc not set), we still
        want to potentially mark objects precious, so that `git gc` does not
        discard shared objects.
        """
        if not opt.auto_gc:
            # Just repair preciousObjects state, and return.
            for project in projects:
                self._SetPreciousObjectsState(project, opt)
            return

        pm = Progress(
            "Garbage collecting", len(projects), delay=False, quiet=opt.quiet
        )
        pm.update(inc=0, msg="prescan")

        tidy_dirs = {}
        for project in projects:
            self._SetPreciousObjectsState(project, opt)

            project.config.SetString("gc.autoDetach", "false")
            # Only call git gc once per objdir, but call pack-refs for the
            # remainder.
            if project.objdir not in tidy_dirs:
                tidy_dirs[project.objdir] = (
                    True,  # Run a full gc.
                    project.bare_git,
                )
            elif project.gitdir not in tidy_dirs:
                tidy_dirs[project.gitdir] = (
                    False,  # Do not run a full gc; just run pack-refs.
                    project.bare_git,
                )

        jobs = opt.jobs

        if jobs < 2:
            for run_gc, bare_git in tidy_dirs.values():
                pm.update(msg=bare_git._project.name)

                if run_gc:
                    bare_git.gc("--auto")
                else:
                    bare_git.pack_refs()
            pm.end()
            return

        cpu_count = os.cpu_count()
        config = {"pack.threads": cpu_count // jobs if cpu_count > jobs else 1}

        threads = set()
        sem = _threading.Semaphore(jobs)

        def tidy_up(run_gc, bare_git):
            pm.start(bare_git._project.name)
            try:
                try:
                    if run_gc:
                        bare_git.gc("--auto", config=config)
                    else:
                        bare_git.pack_refs(config=config)
                except GitError:
                    err_event.set()
                except Exception:
                    err_event.set()
                    raise
            finally:
                pm.finish(bare_git._project.name)
                sem.release()

        for run_gc, bare_git in tidy_dirs.values():
            if err_event.is_set() and opt.fail_fast:
                break
            sem.acquire()
            t = _threading.Thread(
                target=tidy_up,
                args=(
                    run_gc,
                    bare_git,
                ),
            )
            t.daemon = True
            threads.add(t)
            t.start()

        for t in threads:
            t.join()
        pm.end()

    def _ReloadManifest(self, manifest_name, manifest):
        """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.
        """
        if manifest_name:
            # Override calls Unload already.
            manifest.Override(manifest_name)
        else:
            manifest.Unload()

    def UpdateProjectList(self, opt, manifest):
        """Update the cached projects list for |manifest|

        In a multi-manifest checkout, each manifest has its own project.list.

        Args:
            opt: Program options returned from optparse.  See _Options().
            manifest: The manifest to use.

        Returns:
            0: success
            1: failure
        """
        new_project_paths = []
        for project in self.GetProjects(
            None, missing_ok=True, manifest=manifest, all_manifests=False
        ):
            if project.relpath:
                new_project_paths.append(project.relpath)
        file_name = "project.list"
        file_path = os.path.join(manifest.subdir, file_name)
        old_project_paths = []

        if os.path.exists(file_path):
            with open(file_path, "r") as fd:
                old_project_paths = fd.read().split("\n")
            # In reversed order, so subfolders are deleted before parent folder.
            for path in sorted(old_project_paths, reverse=True):
                if not path:
                    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(manifest.topdir, path, ".git")
                    if os.path.exists(gitdir):
                        project = Project(
                            manifest=manifest,
                            name=path,
                            remote=RemoteSpec("origin"),
                            gitdir=gitdir,
                            objdir=gitdir,
                            use_git_worktrees=os.path.isfile(gitdir),
                            worktree=os.path.join(manifest.topdir, path),
                            relpath=path,
                            revisionExpr="HEAD",
                            revisionId=None,
                            groups=None,
                        )
                        if not project.DeleteWorktree(
                            quiet=opt.quiet, force=opt.force_remove_dirty
                        ):
                            return 1

        new_project_paths.sort()
        with open(file_path, "w") as fd:
            fd.write("\n".join(new_project_paths))
            fd.write("\n")
        return 0

    def UpdateCopyLinkfileList(self, manifest):
        """Save all dests of copyfile and linkfile, and update them if needed.

        Returns:
            Whether update was successful.
        """
        new_paths = {}
        new_linkfile_paths = []
        new_copyfile_paths = []
        for project in self.GetProjects(
            None, missing_ok=True, manifest=manifest, all_manifests=False
        ):
            new_linkfile_paths.extend(x.dest for x in project.linkfiles)
            new_copyfile_paths.extend(x.dest for x in project.copyfiles)

        new_paths = {
            "linkfile": new_linkfile_paths,
            "copyfile": new_copyfile_paths,
        }

        copylinkfile_name = "copy-link-files.json"
        copylinkfile_path = os.path.join(manifest.subdir, copylinkfile_name)
        old_copylinkfile_paths = {}

        if os.path.exists(copylinkfile_path):
            with open(copylinkfile_path, "rb") as fp:
                try:
                    old_copylinkfile_paths = json.load(fp)
                except Exception:
                    print(
                        "error: %s is not a json formatted file."
                        % copylinkfile_path,
                        file=sys.stderr,
                    )
                    platform_utils.remove(copylinkfile_path)
                    return False

            need_remove_files = []
            need_remove_files.extend(
                set(old_copylinkfile_paths.get("linkfile", []))
                - set(new_linkfile_paths)
            )
            need_remove_files.extend(
                set(old_copylinkfile_paths.get("copyfile", []))
                - set(new_copyfile_paths)
            )

            for need_remove_file in need_remove_files:
                # Try to remove the updated copyfile or linkfile.
                # So, if the file is not exist, nothing need to do.
                platform_utils.remove(need_remove_file, missing_ok=True)

        # Create copy-link-files.json, save dest path of "copyfile" and
        # "linkfile".
        with open(copylinkfile_path, "w", encoding="utf-8") as fp:
            json.dump(new_paths, fp)
        return True

    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 = manifest.manifest_server
        if not opt.quiet:
            print("Using manifest server %s" % manifest_server)

        if "@" not in manifest_server:
            username = None
            password = None
            if opt.manifest_server_username and opt.manifest_server_password:
                username = opt.manifest_server_username
                password = opt.manifest_server_password
            else:
                try:
                    info = netrc.netrc()
                except IOError:
                    # .netrc file does not exist or could not be opened.
                    pass
                else:
                    try:
                        parse_result = urllib.parse.urlparse(manifest_server)
                        if parse_result.hostname:
                            auth = info.authenticators(parse_result.hostname)
                            if auth:
                                username, _account, password = auth
                            else:
                                print(
                                    "No credentials found for %s in .netrc"
                                    % parse_result.hostname,
                                    file=sys.stderr,
                                )
                    except netrc.NetrcParseError as e:
                        print(
                            "Error parsing .netrc file: %s" % e, file=sys.stderr
                        )

            if username and password:
                manifest_server = manifest_server.replace(
                    "://", "://%s:%s@" % (username, password), 1
                )

        transport = PersistentTransport(manifest_server)
        if manifest_server.startswith("persistent-"):
            manifest_server = manifest_server[len("persistent-") :]

        try:
            server = xmlrpc.client.Server(manifest_server, transport=transport)
            if opt.smart_sync:
                branch = self._GetBranch(manifest.manifestProject)

                if "SYNC_TARGET" in os.environ:
                    target = os.environ["SYNC_TARGET"]
                    [success, manifest_str] = server.GetApprovedManifest(
                        branch, target
                    )
                elif (
                    "TARGET_PRODUCT" in os.environ
                    and "TARGET_BUILD_VARIANT" in os.environ
                ):
                    target = "%s-%s" % (
                        os.environ["TARGET_PRODUCT"],
                        os.environ["TARGET_BUILD_VARIANT"],
                    )
                    [success, manifest_str] = server.GetApprovedManifest(
                        branch, target
                    )
                else:
                    [success, manifest_str] = server.GetApprovedManifest(branch)
            else:
                assert opt.smart_tag
                [success, manifest_str] = server.GetManifest(opt.smart_tag)

            if success:
                manifest_name = os.path.basename(smart_sync_manifest_path)
                try:
                    with open(smart_sync_manifest_path, "w") as f:
                        f.write(manifest_str)
                except IOError as e:
                    print(
                        "error: cannot write manifest to %s:\n%s"
                        % (smart_sync_manifest_path, e),
                        file=sys.stderr,
                    )
                    sys.exit(1)
                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"
                % (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"
                % (manifest.manifest_server, e.errcode, e.errmsg),
                file=sys.stderr,
            )
            sys.exit(1)

        return manifest_name

    def _UpdateAllManifestProjects(self, opt, mp, manifest_name):
        """Fetch & update the local manifest project.

        After syncing the manifest project, if the manifest has any sub
        manifests, those are recursively processed.

        Args:
            opt: Program options returned from optparse.  See _Options().
            mp: the manifestProject to query.
            manifest_name: Manifest file to be reloaded.
        """
        if not mp.standalone_manifest_url:
            self._UpdateManifestProject(opt, mp, manifest_name)

        if mp.manifest.submanifests:
            for submanifest in mp.manifest.submanifests.values():
                child = submanifest.repo_client.manifest
                child.manifestProject.SyncWithPossibleInit(
                    submanifest,
                    current_branch_only=self._GetCurrentBranchOnly(opt, child),
                    verbose=opt.verbose,
                    tags=opt.tags,
                    git_event_log=self.git_event_log,
                )
                self._UpdateAllManifestProjects(
                    opt, child.manifestProject, None
                )

    def _UpdateManifestProject(self, opt, mp, manifest_name):
        """Fetch & update the local manifest project.

        Args:
            opt: Program options returned from optparse.  See _Options().
            mp: the manifestProject to query.
            manifest_name: Manifest file to be reloaded.
        """
        if not opt.local_only:
            start = time.time()
            success = mp.Sync_NetworkHalf(
                quiet=opt.quiet,
                verbose=opt.verbose,
                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=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
            )

        if mp.HasChanges:
            syncbuf = SyncBuffer(mp.config)
            start = time.time()
            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, mp.manifest)

    def ValidateOptions(self, opt, args):
        if opt.force_broken:
            print(
                "warning: -f/--force-broken is now the default behavior, and "
                "the options are deprecated",
                file=sys.stderr,
            )
        if opt.network_only and opt.detach_head:
            self.OptionParser.error("cannot combine -n and -d")
        if opt.network_only and opt.local_only:
            self.OptionParser.error("cannot combine -n and -l")
        if opt.manifest_name and opt.smart_sync:
            self.OptionParser.error("cannot combine -m and -s")
        if opt.manifest_name and opt.smart_tag:
            self.OptionParser.error("cannot combine -m and -t")
        if opt.manifest_server_username or opt.manifest_server_password:
            if not (opt.smart_sync or opt.smart_tag):
                self.OptionParser.error(
                    "-u and -p may only be combined with -s or -t"
                )
            if None in [
                opt.manifest_server_username,
                opt.manifest_server_password,
            ]:
                self.OptionParser.error("both -u and -p must be given")

        if opt.prune is None:
            opt.prune = True

        if opt.auto_gc is None and _AUTO_GC:
            print(
                f"Will run `git gc --auto` because {_REPO_AUTO_GC} is set.",
                f"{_REPO_AUTO_GC} is deprecated and will be removed in a ",
                "future release.  Use `--auto-gc` instead.",
                file=sys.stderr,
            )
            opt.auto_gc = True

    def _ValidateOptionsWithManifest(self, opt, mp):
        """Like ValidateOptions, but after we've updated the manifest.

        Needed to handle sync-xxx option defaults in the manifest.

        Args:
            opt: The options to process.
            mp: The manifest project to pull defaults from.
        """
        if not opt.jobs:
            # If the user hasn't made a choice, use the manifest value.
            opt.jobs = mp.manifest.default.sync_j
        if opt.jobs:
            # If --jobs has a non-default value, propagate it as the default for
            # --jobs-xxx flags too.
            if not opt.jobs_network:
                opt.jobs_network = opt.jobs
            if not opt.jobs_checkout:
                opt.jobs_checkout = opt.jobs
        else:
            # Neither user nor manifest have made a choice, so setup defaults.
            if not opt.jobs_network:
                opt.jobs_network = 1
            if not opt.jobs_checkout:
                opt.jobs_checkout = DEFAULT_LOCAL_JOBS
            opt.jobs = os.cpu_count()

        # Try to stay under user rlimit settings.
        #
        # Since each worker requires at 3 file descriptors to run `git fetch`,
        # use that to scale down the number of jobs.  Unfortunately there isn't
        # an easy way to determine this reliably as systems change, but it was
        # last measured by hand in 2011.
        soft_limit, _ = _rlimit_nofile()
        jobs_soft_limit = max(1, (soft_limit - 5) // 3)
        opt.jobs = min(opt.jobs, jobs_soft_limit)
        opt.jobs_network = min(opt.jobs_network, jobs_soft_limit)
        opt.jobs_checkout = min(opt.jobs_checkout, jobs_soft_limit)

    def Execute(self, opt, args):
        manifest = self.outer_manifest
        if not opt.outer_manifest:
            manifest = self.manifest

        if opt.manifest_name:
            manifest.Override(opt.manifest_name)

        manifest_name = opt.manifest_name
        smart_sync_manifest_path = os.path.join(
            manifest.manifestProject.worktree, "smart_sync_override.xml"
        )

        if opt.clone_bundle is None:
            opt.clone_bundle = manifest.CloneBundle

        if opt.smart_sync or opt.smart_tag:
            manifest_name = self._SmartSyncSetup(
                opt, smart_sync_manifest_path, manifest
            )
        else:
            if os.path.isfile(smart_sync_manifest_path):
                try:
                    platform_utils.remove(smart_sync_manifest_path)
                except OSError as e:
                    print(
                        "error: failed to remove existing smart sync override "
                        "manifest: %s" % e,
                        file=sys.stderr,
                    )

        err_event = multiprocessing.Event()

        rp = manifest.repoProject
        rp.PreSync()
        cb = rp.CurrentBranch
        if cb:
            base = rp.GetBranch(cb).merge
            if not base or not base.startswith("refs/heads/"):
                print(
                    "warning: repo is not tracking a remote branch, so it will "
                    "not receive updates; run `repo init --repo-rev=stable` to "
                    "fix.",
                    file=sys.stderr,
                )

        for m in self.ManifestList(opt):
            if not m.manifestProject.standalone_manifest_url:
                m.manifestProject.PreSync()

        if opt.repo_upgraded:
            _PostRepoUpgrade(manifest, quiet=opt.quiet)

        mp = manifest.manifestProject
        if opt.mp_update:
            self._UpdateAllManifestProjects(opt, mp, manifest_name)
        else:
            print("Skipping update of local manifest project.")

        # Now that the manifests are up-to-date, setup options whose defaults
        # might be in the manifest.
        self._ValidateOptionsWithManifest(opt, mp)

        superproject_logging_data = {}
        self._UpdateProjectsRevisionId(
            opt, args, superproject_logging_data, manifest
        )

        if self.gitc_manifest:
            gitc_manifest_projects = self.GetProjects(args, missing_ok=True)
            gitc_projects = []
            opened_projects = []
            for project in gitc_manifest_projects:
                if (
                    project.relpath in self.gitc_manifest.paths
                    and self.gitc_manifest.paths[project.relpath].old_revision
                ):
                    opened_projects.append(project.relpath)
                else:
                    gitc_projects.append(project.relpath)

            if not args:
                gitc_projects = None

            if gitc_projects != [] and not opt.local_only:
                print(
                    "Updating GITC client: %s"
                    % self.gitc_manifest.gitc_client_name
                )
                manifest = GitcManifest(
                    self.repodir, self.gitc_manifest.gitc_client_name
                )
                if manifest_name:
                    manifest.Override(manifest_name)
                else:
                    manifest.Override(manifest.manifestFile)
                gitc_utils.generate_gitc_manifest(
                    self.gitc_manifest, manifest, gitc_projects
                )
                print("GITC client successfully synced.")

            # The opened projects need to be synced as normal, therefore we
            # 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(manifest.paths[path].worktree, os.getcwd())
                for path in opened_projects
            ]
            if not args:
                return

        all_projects = self.GetProjects(
            args,
            missing_ok=True,
            submodules_ok=opt.fetch_submodules,
            manifest=manifest,
            all_manifests=not opt.this_manifest_only,
        )

        err_network_sync = False
        err_update_projects = False
        err_update_linkfiles = False

        self._fetch_times = _FetchTimes(manifest)
        if not opt.local_only:
            with multiprocessing.Manager() as manager:
                with ssh.ProxyManager(manager) as ssh_proxy:
                    # Initialize the socket dir once in the parent.
                    ssh_proxy.sock()
                    result = self._FetchMain(
                        opt, args, all_projects, err_event, ssh_proxy, manifest
                    )
                    all_projects = result.all_projects

            if opt.network_only:
                return

            # If we saw an error, exit with code 1 so that other scripts can
            # check.
            if err_event.is_set():
                err_network_sync = True
                if opt.fail_fast:
                    print(
                        "\nerror: Exited sync due to fetch errors.\n"
                        "Local checkouts *not* updated. Resolve network issues "
                        "& retry.\n"
                        "`repo sync -l` will update some local checkouts.",
                        file=sys.stderr,
                    )
                    sys.exit(1)

        for m in self.ManifestList(opt):
            if m.IsMirror or m.IsArchive:
                # Bail out now, we have no working tree.
                continue

            if self.UpdateProjectList(opt, m):
                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(m)
            if err_update_linkfiles:
                err_event.set()
                if opt.fail_fast:
                    print(
                        "\nerror: Local update copyfile or linkfile failed.",
                        file=sys.stderr,
                    )
                    sys.exit(1)

        err_results = []
        # NB: We don't exit here because this is the last step.
        err_checkout = not self._Checkout(all_projects, opt, err_results)
        if err_checkout:
            err_event.set()

        printed_notices = set()
        # If there's a notice that's supposed to print at the end of the sync,
        # print it now...  But avoid printing duplicate messages, and preserve
        # order.
        for m in sorted(self.ManifestList(opt), key=lambda x: x.path_prefix):
            if m.notice and m.notice not in printed_notices:
                print(m.notice)
                printed_notices.add(m.notice)

        # If we saw an error, exit with code 1 so that other scripts can check.
        if err_event.is_set():
            # Add a new line so it's easier to read.
            print("\n", file=sys.stderr)

            def print_and_log(err_msg):
                self.git_event_log.ErrorEvent(err_msg)
                print(err_msg, file=sys.stderr)

            print_and_log("error: Unable to fully sync the tree")
            if err_network_sync:
                print_and_log("error: Downloading network changes failed.")
            if err_update_projects:
                print_and_log("error: Updating local project lists failed.")
            if err_update_linkfiles:
                print_and_log("error: Updating copyfiles or linkfiles failed.")
            if err_checkout:
                print_and_log("error: Checking out local projects failed.")
                if err_results:
                    # Don't log repositories, as it may contain sensitive info.
                    print(
                        "Failing repos:\n%s" % "\n".join(err_results),
                        file=sys.stderr,
                    )
            # Not useful to log.
            print(
                'Try re-running with "-j1 --fail-fast" to exit at the first '
                "error.",
                file=sys.stderr,
            )
            sys.exit(1)

        # Log the previous sync analysis state from the config.
        self.git_event_log.LogDataConfigEvents(
            mp.config.GetSyncAnalysisStateData(), "previous_sync_state"
        )

        # Update and log with the new sync analysis state.
        mp.config.UpdateSyncAnalysisState(opt, superproject_logging_data)
        self.git_event_log.LogDataConfigEvents(
            mp.config.GetSyncAnalysisStateData(), "current_sync_state"
        )

        if not opt.quiet:
            print("repo sync has finished successfully.")


def _PostRepoUpgrade(manifest, quiet=False):
    # Link the docs for the internal .repo/ layout for people.
    link = os.path.join(manifest.repodir, "internal-fs-layout.md")
    if not platform_utils.islink(link):
        target = os.path.join("repo", "docs", "internal-fs-layout.md")
        try:
            platform_utils.symlink(target, link)
        except Exception:
            pass

    wrapper = Wrapper()
    if wrapper.NeedSetupGnuPG():
        wrapper.SetupGnuPG(quiet)
    for project in manifest.projects:
        if project.Exists:
            project.PostRepoUpgrade()


def _PostRepoFetch(rp, repo_verify=True, verbose=False):
    if rp.HasChanges:
        print("info: A new version of repo is available", file=sys.stderr)
        wrapper = Wrapper()
        try:
            rev = rp.bare_git.describe(rp.GetRevisionId())
        except GitError:
            rev = None
        _, new_rev = wrapper.check_repo_rev(
            rp.gitdir, rev, repo_verify=repo_verify
        )
        # See if we're held back due to missing signed tag.
        current_revid = rp.bare_git.rev_parse("HEAD")
        new_revid = rp.bare_git.rev_parse("--verify", new_rev)
        if current_revid != new_revid:
            # We want to switch to the new rev, but also not trash any
            # uncommitted changes.  This helps with local testing/hacking.
            # If a local change has been made, we will throw that away.
            # We also have to make sure this will switch to an older commit if
            # that's the latest tag in order to support release rollback.
            try:
                rp.work_git.reset("--keep", new_rev)
            except GitError as e:
                sys.exit(str(e))
            print("info: Restarting repo with latest version", file=sys.stderr)
            raise RepoChangedException(["--repo-upgraded"])
        else:
            print(
                "warning: Skipped upgrade to unverified version",
                file=sys.stderr,
            )
    else:
        if verbose:
            print(
                "repo version %s is current" % rp.work_git.describe(HEAD),
                file=sys.stderr,
            )


class _FetchTimes(object):
    _ALPHA = 0.5

    def __init__(self, manifest):
        self._path = os.path.join(manifest.repodir, ".repo_fetchtimes.json")
        self._saved = None
        self._seen = {}

    def Get(self, project):
        self._Load()
        return self._saved.get(project.name, _ONE_DAY_S)

    def Set(self, project, t):
        name = project.name

        # For shared projects, save the longest time.
        self._seen[name] = max(self._seen.get(name, 0), t)

    def _Load(self):
        if self._saved is None:
            try:
                with open(self._path) as f:
                    self._saved = json.load(f)
            except (IOError, ValueError):
                platform_utils.remove(self._path, missing_ok=True)
                self._saved = {}

    def Save(self):
        if self._saved is None:
            return

        for name, t in self._seen.items():
            # Keep a moving average across the previous/current sync runs.
            old = self._saved.get(name, t)
            self._seen[name] = (self._ALPHA * t) + ((1 - self._ALPHA) * old)

        try:
            with open(self._path, "w") as f:
                json.dump(self._seen, f, indent=2)
        except (IOError, TypeError):
            platform_utils.remove(self._path, missing_ok=True)


# This is a replacement for xmlrpc.client.Transport using urllib2
# and supporting persistent-http[s]. It cannot change hosts from
# request to request like the normal transport, the real url
# is passed during initialization.


class PersistentTransport(xmlrpc.client.Transport):
    def __init__(self, orig_host):
        self.orig_host = orig_host

    def request(self, host, handler, request_body, verbose=False):
        with GetUrlCookieFile(self.orig_host, not verbose) as (
            cookiefile,
            proxy,
        ):
            # Python doesn't understand cookies with the #HttpOnly_ prefix
            # Since we're only using them for HTTP, copy the file temporarily,
            # stripping those prefixes away.
            if cookiefile:
                tmpcookiefile = tempfile.NamedTemporaryFile(mode="w")
                tmpcookiefile.write("# HTTP Cookie File")
                try:
                    with open(cookiefile) as f:
                        for line in f:
                            if line.startswith("#HttpOnly_"):
                                line = line[len("#HttpOnly_") :]
                            tmpcookiefile.write(line)
                    tmpcookiefile.flush()

                    cookiejar = cookielib.MozillaCookieJar(tmpcookiefile.name)
                    try:
                        cookiejar.load()
                    except cookielib.LoadError:
                        cookiejar = cookielib.CookieJar()
                finally:
                    tmpcookiefile.close()
            else:
                cookiejar = cookielib.CookieJar()

            proxyhandler = urllib.request.ProxyHandler
            if proxy:
                proxyhandler = urllib.request.ProxyHandler(
                    {"http": proxy, "https": proxy}
                )

            opener = urllib.request.build_opener(
                urllib.request.HTTPCookieProcessor(cookiejar), proxyhandler
            )

            url = urllib.parse.urljoin(self.orig_host, handler)
            parse_results = urllib.parse.urlparse(url)

            scheme = parse_results.scheme
            if scheme == "persistent-http":
                scheme = "http"
            if scheme == "persistent-https":
                # If we're proxying through persistent-https, use http. The
                # proxy itself will do the https.
                if proxy:
                    scheme = "http"
                else:
                    scheme = "https"

            # Parse out any authentication information using the base class.
            host, extra_headers, _ = self.get_host_info(parse_results.netloc)

            url = urllib.parse.urlunparse(
                (
                    scheme,
                    host,
                    parse_results.path,
                    parse_results.params,
                    parse_results.query,
                    parse_results.fragment,
                )
            )

            request = urllib.request.Request(url, request_body)
            if extra_headers is not None:
                for name, header in extra_headers:
                    request.add_header(name, header)
            request.add_header("Content-Type", "text/xml")
            try:
                response = opener.open(request)
            except urllib.error.HTTPError as e:
                if e.code == 501:
                    # We may have been redirected through a login process
                    # but our POST turned into a GET. Retry.
                    response = opener.open(request)
                else:
                    raise

            p, u = xmlrpc.client.getparser()
            # Response should be fairly small, so read it all at once.
            # This way we can show it to the user in case of error (e.g. HTML).
            data = response.read()
            try:
                p.feed(data)
            except xml.parsers.expat.ExpatError as e:
                raise IOError(
                    f"Parsing the manifest failed: {e}\n"
                    f"Please report this to your manifest server admin.\n"
                    f'Here is the full response:\n{data.decode("utf-8")}'
                )
            p.close()
            return u.close()

    def close(self):
        pass
