def testGetManifestsBranch(self):
        # pylint: disable=protected-access
        func = git.ManifestCheckout._GetManifestsBranch
        manifest = self.manifest_dir
        repo_root = self.tempdir

        # pylint: disable=unused-argument
        def reconfig(merge='master', origin='origin'):
            if merge is not None:
                merge = 'refs/heads/%s' % merge
            for key in ('merge', 'origin'):
                val = locals()[key]
                key = 'branch.default.%s' % key
                if val is None:
                    git.RunGit(manifest, ['config', '--unset', key],
                               check=False)
                else:
                    git.RunGit(manifest, ['config', key, val])

        # First, verify our assumptions about a fresh repo init are correct.
        self.assertEqual('default', git.GetCurrentBranch(manifest))
        self.assertEqual('master', func(repo_root))

        # Ensure we can handle a missing origin; this can occur jumping between
        # branches, and can be worked around.
        reconfig(origin=None)
        self.assertEqual('default', git.GetCurrentBranch(manifest))
        self.assertEqual('master', func(repo_root))

        def assertExcept(message, **kwargs):
            reconfig(**kwargs)
            self.assertRaises2(OSError,
                               func,
                               repo_root,
                               ex_msg=message,
                               check_attrs={'errno': errno.ENOENT})

        # No merge target means the configuration isn't usable, period.
        assertExcept('git tracking configuration for that branch is broken',
                     merge=None)

        # Ensure we detect if we're on the wrong branch, even if it has
        # tracking setup.
        git.RunGit(manifest, ['checkout', '-t', 'origin/master', '-b', 'test'])
        assertExcept("It should be checked out to 'default'")

        # Ensure we handle detached HEAD w/ an appropriate exception.
        git.RunGit(manifest, ['checkout', '--detach', 'test'])
        assertExcept("It should be checked out to 'default'")

        # Finally, ensure that if the default branch is non-existant, we still throw
        # a usable exception.
        git.RunGit(manifest, ['branch', '-d', 'default'])
        assertExcept("It should be checked out to 'default'")
Пример #2
0
    def GitBranch(self, project):
        """Returns the project's current branch on disk.

    Args:
      project: The repo_manifest.Project in question.
    """
        return git.GetCurrentBranch(self.AbsoluteProjectPath(project))
def main(argv):
    parser = GetParser()
    options = parser.parse_args(argv)
    options.Freeze()

    overlay_dir = os.path.abspath(_OVERLAY_DIR % {'srcroot': options.srcroot})
    android_package_dir = os.path.join(overlay_dir, constants.ANDROID_CP)
    version_to_uprev = None
    subpaths = None

    (unstable_ebuild,
     stable_ebuilds) = FindAndroidCandidates(android_package_dir)

    if options.force_version:
        version_to_uprev = options.force_version
        subpaths = IsBuildIdValid(options.android_bucket_url,
                                  options.android_build_branch,
                                  version_to_uprev)
        if not subpaths:
            logging.error('Requested build %s is not valid' % version_to_uprev)
    else:
        version_to_uprev, subpaths = GetLatestBuild(
            options.android_bucket_url, options.android_build_branch)

    acls = MakeAclDict(android_package_dir)
    CopyToArcBucket(options.android_bucket_url, options.android_build_branch,
                    version_to_uprev, subpaths, options.arc_bucket_url, acls)

    stable_candidate = portage_util.BestEBuild(stable_ebuilds)

    if stable_candidate:
        logging.info('Stable candidate found %s' % stable_candidate.version)
    else:
        logging.info('No stable candidate found.')

    tracking_branch = 'remotes/m/%s' % os.path.basename(
        options.tracking_branch)
    existing_branch = git.GetCurrentBranch(android_package_dir)
    work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
                                                tracking_branch,
                                                android_package_dir)
    work_branch.CreateBranch()

    # In the case of uprevving overlays that have patches applied to them,
    # include the patched changes in the stabilizing branch.
    if existing_branch:
        git.RunGit(overlay_dir, ['rebase', existing_branch])

    android_version_atom = MarkAndroidEBuildAsStable(
        stable_candidate, unstable_ebuild, constants.ANDROID_PN,
        version_to_uprev, android_package_dir, options.android_build_branch,
        options.arc_bucket_url)
    if android_version_atom:
        if options.boards:
            cros_mark_as_stable.CleanStalePackages(options.srcroot,
                                                   options.boards.split(':'),
                                                   [android_version_atom])

        # Explicit print to communicate to caller.
        print('ANDROID_VERSION_ATOM=%s' % android_version_atom)
Пример #4
0
def _DoWeHaveLocalCommits(stable_branch, tracking_branch, cwd):
    """Returns true if there are local commits."""
    current_branch = git.GetCurrentBranch(cwd)

    if current_branch != stable_branch:
        return False
    output = git.RunGit(cwd,
                        ['rev-parse', 'HEAD', tracking_branch]).output.split()
    return output[0] != output[1]
Пример #5
0
def main(argv):
    parser = GetParser()
    options = parser.parse_args(argv)
    options.Freeze()

    overlay_dir = os.path.abspath(_OVERLAY_DIR % {'srcroot': options.srcroot})
    android_package_dir = os.path.join(overlay_dir, constants.ANDROID_CP)
    version_to_uprev = None

    (unstable_ebuild,
     stable_ebuilds) = FindAndroidCandidates(android_package_dir)
    acls = MakeAclDict(android_package_dir)
    # Mirror artifacts, i.e., images and some sdk tools (e.g., adb, aapt).
    version_to_uprev = MirrorArtifacts(options.android_bucket_url,
                                       options.android_build_branch,
                                       options.arc_bucket_url, acls,
                                       constants.ANDROID_BUILD_TARGETS,
                                       options.force_version)

    # Mirror GTS.
    MirrorArtifacts(options.android_bucket_url,
                    options.android_gts_build_branch, options.arc_bucket_url,
                    acls, constants.ANDROID_GTS_BUILD_TARGETS)

    stable_candidate = portage_util.BestEBuild(stable_ebuilds)

    if stable_candidate:
        logging.info('Stable candidate found %s' % stable_candidate.version)
    else:
        logging.info('No stable candidate found.')

    tracking_branch = 'remotes/m/%s' % os.path.basename(
        options.tracking_branch)
    existing_branch = git.GetCurrentBranch(android_package_dir)
    work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
                                                tracking_branch,
                                                android_package_dir)
    work_branch.CreateBranch()

    # In the case of uprevving overlays that have patches applied to them,
    # include the patched changes in the stabilizing branch.
    if existing_branch:
        git.RunGit(overlay_dir, ['rebase', existing_branch])

    android_version_atom = MarkAndroidEBuildAsStable(
        stable_candidate, unstable_ebuild, constants.ANDROID_PN,
        version_to_uprev, android_package_dir, options.android_build_branch,
        options.arc_bucket_url)
    if android_version_atom:
        if options.boards:
            cros_mark_as_stable.CleanStalePackages(options.srcroot,
                                                   options.boards.split(':'),
                                                   [android_version_atom])

        # Explicit print to communicate to caller.
        print('ANDROID_VERSION_ATOM=%s' % android_version_atom)
Пример #6
0
    def testGetManifestsBranch(self):
        func = git.ManifestCheckout._GetManifestsBranch
        manifest = self.manifest_dir
        repo_root = self.tempdir

        # pylint: disable=W0613
        def reconfig(merge='master', origin='origin'):
            if merge is not None:
                merge = 'refs/heads/%s' % merge
            for key in ('merge', 'origin'):
                val = locals()[key]
                key = 'branch.default.%s' % key
                if val is None:
                    git.RunGit(manifest, ['config', '--unset', key],
                               error_code_ok=True)
                else:
                    git.RunGit(manifest, ['config', key, val])

        # First, verify our assumptions about a fresh repo init are correct.
        self.assertEqual('default', git.GetCurrentBranch(manifest))
        self.assertEqual('master', func(repo_root))

        # Ensure we can handle a missing origin; this can occur jumping between
        # branches, and can be worked around.
        reconfig(origin=None)
        self.assertEqual('default', git.GetCurrentBranch(manifest))
        self.assertEqual('master', func(repo_root))

        # TODO(ferringb): convert this over to assertRaises2
        def assertExcept(message, **kwds):
            reconfig(**kwds)
            try:
                func(repo_root)
                assert "Testing for %s, an exception wasn't thrown." % (
                    message, )
            except OSError, e:
                self.assertEqual(e.errno, errno.ENOENT)
                self.assertTrue(
                    message in str(e),
                    msg="Couldn't find string %r in error message %r" %
                    (message, str(e)))
Пример #7
0
def UpdateBinhostConfFile(path, key, value):
  """Update binhost config file file with key=value.

  Args:
    path: Filename to update.
    key: Key to update.
    value: New value for key.
  """
  cwd, filename = os.path.split(os.path.abspath(path))
  osutils.SafeMakedirs(cwd)
  if not git.GetCurrentBranch(cwd):
    git.CreatePushBranch(constants.STABLE_EBUILD_BRANCH, cwd, sync=False)
  osutils.WriteFile(path, '', mode='a')
  if UpdateLocalFile(path, value, key):
    desc = '%s: %s %s' % (filename, 'updating' if value else 'clearing', key)
    git.AddPath(path)
    git.Commit(cwd, desc)
Пример #8
0
def UpdateBinhostConfFile(path, key, value):
    """Update binhost config file file with key=value.

  Args:
    path: Filename to update.
    key: Key to update.
    value: New value for key.
  """
    cwd = os.path.dirname(os.path.abspath(path))
    filename = os.path.basename(path)
    osutils.SafeMakedirs(cwd)
    if not git.GetCurrentBranch(cwd):
        git.CreatePushBranch(constants.STABLE_EBUILD_BRANCH, cwd, sync=False)
    osutils.WriteFile(path, '', mode='a')
    UpdateLocalFile(path, value, key)
    cros_build_lib.RunCommand(['git', 'add', filename], cwd=cwd)
    description = '%s: updating %s' % (os.path.basename(filename), key)
    cros_build_lib.RunCommand(['git', 'commit', '-m', description], cwd=cwd)
Пример #9
0
    def Pin(self, commit_hash):
        """Attempt to pin the project to the specified commit hash.

    Arguments:
      commit_hash: The commit to pin the project to.

    Raises:
      ProjectException when an error occurs.
    """
        self._PrepareProject()
        if git.GetCurrentBranch(self.abs_path):
            cros_build_lib.Warning(
                "Not pinning project %s that's checked out to a "
                'development branch.' % self.rel_path)
        elif (commit_hash
              and (commit_hash != git.GetGitRepoRevision(self.abs_path))):
            print 'Pinning project %s' % self.rel_path
            self._ResetProject(commit_hash)
        else:
            cros_build_lib.Debug('Skipping project %s, already pinned' %
                                 self.rel_path)
def main(argv):
    parser = GetParser()
    options = parser.parse_args(argv)
    options.Freeze()
    chrome_rev = options.revision

    if options.force_version and chrome_rev not in (
            constants.CHROME_REV_SPEC, constants.CHROME_REV_LATEST):
        parser.error('--force_version is not compatible with the %r '
                     'option.' % (chrome_rev, ))

    overlay_dir = os.path.abspath(_OVERLAY_DIR % {'srcroot': options.srcroot})
    chrome_package_dir = os.path.join(overlay_dir, constants.CHROME_CP)
    version_to_uprev = None
    commit_to_use = None
    sticky_branch = None

    (unstable_ebuild,
     stable_ebuilds) = FindChromeCandidates(chrome_package_dir)

    if chrome_rev == constants.CHROME_REV_LOCAL:
        if 'CHROME_ROOT' in os.environ:
            chrome_root = os.environ['CHROME_ROOT']
        else:
            chrome_root = os.path.join(os.environ['HOME'], 'chrome_root')

        version_to_uprev = _GetTipOfTrunkVersionFile(chrome_root)
        commit_to_use = 'Unknown'
        logging.info('Using local source, versioning is untrustworthy.')
    elif chrome_rev == constants.CHROME_REV_SPEC:
        if '.' in options.force_version:
            version_to_uprev = options.force_version
        else:
            commit_to_use = options.force_version
            if '@' in commit_to_use:
                commit_to_use = commit_to_use.rpartition('@')[2]
            version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
                                                      commit_to_use)
    elif chrome_rev == constants.CHROME_REV_TOT:
        commit_to_use = gob_util.GetTipOfTrunkRevision(options.chrome_url)
        version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
                                                  commit_to_use)
    elif chrome_rev == constants.CHROME_REV_LATEST:
        if options.force_version:
            if '.' not in options.force_version:
                parser.error(
                    '%s only accepts released Chrome versions, not SVN or '
                    'Git revisions.' % (chrome_rev, ))
            version_to_uprev = options.force_version
        else:
            version_to_uprev = GetLatestRelease(options.chrome_url)
    else:
        sticky_ebuild = _GetStickyEBuild(stable_ebuilds)
        sticky_version = sticky_ebuild.chrome_version
        sticky_branch = sticky_version.rpartition('.')[0]
        version_to_uprev = GetLatestRelease(options.chrome_url, sticky_branch)

    stable_candidate = FindChromeUprevCandidate(stable_ebuilds, chrome_rev,
                                                sticky_branch)

    if stable_candidate:
        logging.info('Stable candidate found %s' % stable_candidate)
    else:
        logging.info('No stable candidate found.')

    tracking_branch = 'remotes/m/%s' % os.path.basename(
        options.tracking_branch)
    existing_branch = git.GetCurrentBranch(chrome_package_dir)
    work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
                                                tracking_branch,
                                                chrome_package_dir)
    work_branch.CreateBranch()

    # In the case of uprevving overlays that have patches applied to them,
    # include the patched changes in the stabilizing branch.
    if existing_branch:
        git.RunGit(chrome_package_dir, ['rebase', existing_branch])

    chrome_version_atom = MarkChromeEBuildAsStable(
        stable_candidate, unstable_ebuild, 'chromeos-chrome', chrome_rev,
        version_to_uprev, commit_to_use, chrome_package_dir)
    if chrome_version_atom:
        if options.boards:
            cros_mark_as_stable.CleanStalePackages(options.srcroot,
                                                   options.boards.split(':'),
                                                   [chrome_version_atom])

        # If we did rev Chrome, now is a good time to uprev other packages.
        for other_ebuild in constants.OTHER_CHROME_PACKAGES:
            other_ebuild_name = os.path.basename(other_ebuild)
            other_package_dir = os.path.join(overlay_dir, other_ebuild)
            (other_unstable_ebuild,
             other_stable_ebuilds) = FindChromeCandidates(other_package_dir)
            other_stable_candidate = FindChromeUprevCandidate(
                other_stable_ebuilds, chrome_rev, sticky_branch)
            revved_atom = MarkChromeEBuildAsStable(
                other_stable_candidate, other_unstable_ebuild,
                other_ebuild_name, chrome_rev, version_to_uprev, commit_to_use,
                other_package_dir)
            if revved_atom and options.boards:
                cros_mark_as_stable.CleanStalePackages(
                    options.srcroot, options.boards.split(':'), [revved_atom])

    # Explicit print to communicate to caller.
    if chrome_version_atom:
        print('CHROME_VERSION_ATOM=%s' % chrome_version_atom)
Пример #11
0
def main(_argv):
    usage_options = '|'.join(constants.VALID_CHROME_REVISIONS)
    usage = '%s OPTIONS [%s]' % (__file__, usage_options)
    parser = optparse.OptionParser(usage)
    parser.add_option('-b', '--boards', default='x86-generic')
    parser.add_option('-c', '--chrome_url', default=gclient.GetBaseURLs()[0])
    parser.add_option('-f', '--force_revision', default=None)
    parser.add_option('-s',
                      '--srcroot',
                      default=os.path.join(os.environ['HOME'], 'trunk', 'src'),
                      help='Path to the src directory')
    parser.add_option('-t',
                      '--tracking_branch',
                      default='cros/master',
                      help='Branch we are tracking changes against')
    (options, args) = parser.parse_args()

    if len(args) != 1 or args[0] not in constants.VALID_CHROME_REVISIONS:
        parser.error('Commit requires arg set to one of %s.' %
                     constants.VALID_CHROME_REVISIONS)

    overlay_dir = os.path.abspath(_CHROME_OVERLAY_DIR %
                                  {'srcroot': options.srcroot})
    chrome_rev = args[0]
    version_to_uprev = None
    commit_to_use = None
    sticky_branch = None

    (unstable_ebuild, stable_ebuilds) = FindChromeCandidates(overlay_dir)

    if chrome_rev == constants.CHROME_REV_LOCAL:
        if 'CHROME_ROOT' in os.environ:
            chrome_root = os.environ['CHROME_ROOT']
        else:
            chrome_root = os.path.join(os.environ['HOME'], 'chrome_root')

        version_to_uprev = _GetTipOfTrunkVersionFile(chrome_root)
        commit_to_use = 'Unknown'
        cros_build_lib.Info('Using local source, versioning is untrustworthy.')
    elif chrome_rev == constants.CHROME_REV_SPEC:
        commit_to_use = options.force_revision
        if '@' in commit_to_use:
            commit_to_use = ParseMaxRevision(commit_to_use)
        version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
                                                  commit_to_use)
    elif chrome_rev == constants.CHROME_REV_TOT:
        commit_to_use = gclient.GetTipOfTrunkSvnRevision(options.chrome_url)
        version_to_uprev = _GetSpecificVersionUrl(options.chrome_url,
                                                  commit_to_use)
    elif chrome_rev == constants.CHROME_REV_LATEST:
        version_to_uprev = _GetLatestRelease(options.chrome_url)
    else:
        sticky_ebuild = _GetStickyEBuild(stable_ebuilds)
        sticky_version = sticky_ebuild.chrome_version
        sticky_branch = sticky_version.rpartition('.')[0]
        version_to_uprev = _GetLatestRelease(options.chrome_url, sticky_branch)

    stable_candidate = FindChromeUprevCandidate(stable_ebuilds, chrome_rev,
                                                sticky_branch)

    if stable_candidate:
        cros_build_lib.Info('Stable candidate found %s' % stable_candidate)
    else:
        cros_build_lib.Info('No stable candidate found.')

    tracking_branch = 'remotes/m/%s' % os.path.basename(
        options.tracking_branch)
    existing_branch = git.GetCurrentBranch(overlay_dir)
    work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
                                                tracking_branch, overlay_dir)
    work_branch.CreateBranch()

    # In the case of uprevving overlays that have patches applied to them,
    # include the patched changes in the stabilizing branch.
    if existing_branch:
        cros_build_lib.RunCommand(['git', 'rebase', existing_branch],
                                  cwd=overlay_dir)

    chrome_version_atom = MarkChromeEBuildAsStable(stable_candidate,
                                                   unstable_ebuild, chrome_rev,
                                                   version_to_uprev,
                                                   commit_to_use, overlay_dir)
    # Explicit print to communicate to caller.
    if chrome_version_atom:
        cros_mark_as_stable.CleanStalePackages(options.boards.split(':'),
                                               [chrome_version_atom])
        print 'CHROME_VERSION_ATOM=%s' % chrome_version_atom
 def testStartBranch(self):
   """Test Repository.StartBranch creates a git branch."""
   self.repo.StartBranch('my-branch')
   project_branch = git.GetCurrentBranch(self.project_path)
   self.assertEqual(project_branch, 'my-branch')
Пример #13
0
def UprevStableEBuild(ebuild_dir,
                      commit_to_use,
                      date_of_commit,
                      tracking_branch='cros/master'):
    """Checks if there already if a stable Mojo ebuild for the given commit.

  If there already is a stable Mojo ebuild for the given commit, this
  function does nothing and returns None. Otherwise creates a stabilization
  branch with a single commit that creates a new stable ebuild and deletes
  all other stable ebuilds.

  Args:
    ebuild_dir: Path to the directory holding Mojo ebuilds.
    commit_to_use: The upstream Mojo commit id.
    date_of_commit: The date of the commit.
    tracking_branch: The branch that the stabilization branch should track.

  Returns:
    None or a version atom describing the newly created ebuild.
  """
    # There is no version number or other monotonically increasing value
    # that is suitable to use as a version number except for the point
    # in time that a commit was added to the repository. So we use that
    # for now.
    pvr = date_of_commit.strftime('0.%Y%m%d.%H%M%S-r1')
    mojo_stable_pn = '%s-%s.ebuild' % (MOJO_PN, pvr)

    # Find existing stable ebuilds and only add a new one if there's a
    # newer commit.
    existing_ebuilds = GetStableEBuilds(ebuild_dir)
    if mojo_stable_pn in existing_ebuilds:
        return None

    # OK. First create a stablizing branch.
    tracking_branch_full = 'remotes/m/%s' % os.path.basename(tracking_branch)
    existing_branch = git.GetCurrentBranch(ebuild_dir)
    work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
                                                tracking_branch_full,
                                                ebuild_dir)
    work_branch.CreateBranch()

    # In the case of uprevving overlays that have patches applied to them,
    # include the patched changes in the stabilizing branch.
    if existing_branch:
        git.RunGit(ebuild_dir, ['rebase', existing_branch])

    # Create a new ebuild.
    unstable_ebuild_path = os.path.join(
        ebuild_dir, MOJO_PN + portage_util.WORKON_EBUILD_SUFFIX)
    new_stable_ebuild_path = os.path.join(ebuild_dir, mojo_stable_pn)
    variables = {'MOJO_REVISION': commit_to_use}
    portage_util.EBuild.MarkAsStable(unstable_ebuild_path,
                                     new_stable_ebuild_path,
                                     variables,
                                     make_stable=True)

    # Add it to the repo.
    git.RunGit(ebuild_dir, ['add', new_stable_ebuild_path])

    # Nuke the now stale older ebuilds.
    for f in existing_ebuilds:
        git.RunGit(ebuild_dir, ['rm', '-f', f])

    # ... and finally commit the change.
    portage_util.EBuild.CommitChange(
        'Updated %s to upstream commit %s.' % (MOJO_CP, commit_to_use),
        ebuild_dir)
    # Return version atom for newly created ebuild.
    return MOJO_CP + '-' + pvr
Пример #14
0
def main(_argv):
    parser = optparse.OptionParser('cros_mark_as_stable OPTIONS packages')
    parser.add_option('--all',
                      action='store_true',
                      help='Mark all packages as stable.')
    parser.add_option('-b',
                      '--boards',
                      default='',
                      help='Colon-separated list of boards')
    parser.add_option('--drop_file',
                      help='File to list packages that were revved.')
    parser.add_option('--dryrun',
                      action='store_true',
                      help='Passes dry-run to git push if pushing a change.')
    parser.add_option('-o',
                      '--overlays',
                      help='Colon-separated list of overlays to modify.')
    parser.add_option('-p',
                      '--packages',
                      help='Colon separated list of packages to rev.')
    parser.add_option('-r',
                      '--srcroot',
                      default=os.path.join(constants.SOURCE_ROOT, 'src'),
                      help='Path to root src directory.')
    parser.add_option('--verbose',
                      action='store_true',
                      help='Prints out debug info.')
    (options, args) = parser.parse_args()

    portage_utilities.EBuild.VERBOSE = options.verbose

    if len(args) != 1:
        _PrintUsageAndDie('Must specify a valid command [commit, push]')

    command = args[0]
    package_list = None
    if options.packages:
        package_list = options.packages.split(':')

    _CheckSaneArguments(command, options)
    if options.overlays:
        overlays = {}
        for path in options.overlays.split(':'):
            if not os.path.isdir(path):
                cros_build_lib.Die('Cannot find overlay: %s' % path)
            overlays[path] = []
    else:
        cros_build_lib.Warning('Missing --overlays argument')
        overlays = {
            '%s/private-overlays/chromeos-overlay' % options.srcroot: [],
            '%s/third_party/chromiumos-overlay' % options.srcroot: []
        }

    manifest = git.ManifestCheckout.Cached(options.srcroot)

    if command == 'commit':
        portage_utilities.BuildEBuildDictionary(overlays, options.all,
                                                package_list)

    # Contains the array of packages we actually revved.
    revved_packages = []
    new_package_atoms = []

    # Slight optimization hack: process the chromiumos overlay before any other
    # cros-workon overlay first so we can do background cache generation in it.
    # A perfect solution would walk all the overlays, figure out any dependencies
    # between them (with layout.conf), and then process them in dependency order.
    # However, this operation isn't slow enough to warrant that level of
    # complexity, so we'll just special case the main overlay.
    #
    # Similarly, generate the cache in the portage-stable tree asap.  We know
    # we won't have any cros-workon packages in there, so generating the cache
    # is the only thing it'll be doing.  The chromiumos overlay instead might
    # have revbumping to do before it can generate the cache.
    keys = overlays.keys()
    for overlay in ('/third_party/chromiumos-overlay',
                    '/third_party/portage-stable'):
        for k in keys:
            if k.endswith(overlay):
                keys.remove(k)
                keys.insert(0, k)
                break

    with parallel.BackgroundTaskRunner(portage_utilities.RegenCache) as queue:
        for overlay in keys:
            ebuilds = overlays[overlay]
            if not os.path.isdir(overlay):
                cros_build_lib.Warning("Skipping %s" % overlay)
                continue

            # Note we intentionally work from the non push tracking branch;
            # everything built thus far has been against it (meaning, http mirrors),
            # thus we should honor that.  During the actual push, the code switches
            # to the correct urls, and does an appropriate rebasing.
            tracking_branch = git.GetTrackingBranchViaManifest(
                overlay, manifest=manifest)[1]

            if command == 'push':
                PushChange(constants.STABLE_EBUILD_BRANCH,
                           tracking_branch,
                           options.dryrun,
                           cwd=overlay)
            elif command == 'commit':
                existing_branch = git.GetCurrentBranch(overlay)
                work_branch = GitBranch(constants.STABLE_EBUILD_BRANCH,
                                        tracking_branch,
                                        cwd=overlay)
                work_branch.CreateBranch()
                if not work_branch.Exists():
                    cros_build_lib.Die(
                        'Unable to create stabilizing branch in %s' % overlay)

                # In the case of uprevving overlays that have patches applied to them,
                # include the patched changes in the stabilizing branch.
                if existing_branch:
                    cros_build_lib.RunCommand(
                        ['git', 'rebase', existing_branch],
                        print_cmd=False,
                        cwd=overlay)

                messages = []
                for ebuild in ebuilds:
                    if options.verbose:
                        cros_build_lib.Info('Working on %s', ebuild.package)
                    try:
                        new_package = ebuild.RevWorkOnEBuild(
                            options.srcroot, manifest)
                        if new_package:
                            revved_packages.append(ebuild.package)
                            new_package_atoms.append('=%s' % new_package)
                            messages.append(_GIT_COMMIT_MESSAGE %
                                            ebuild.package)
                    except (OSError, IOError):
                        cros_build_lib.Warning(
                            'Cannot rev %s\n' % ebuild.package +
                            'Note you will have to go into %s '
                            'and reset the git repo yourself.' % overlay)
                        raise

                if messages:
                    portage_utilities.EBuild.CommitChange(
                        '\n\n'.join(messages), overlay)

                if cros_build_lib.IsInsideChroot():
                    # Regenerate caches if need be.  We do this all the time to
                    # catch when users make changes without updating cache files.
                    queue.put([overlay])

    if command == 'commit':
        if cros_build_lib.IsInsideChroot():
            CleanStalePackages(options.boards.split(':'), new_package_atoms)
        if options.drop_file:
            osutils.WriteFile(options.drop_file, ' '.join(revved_packages))