| Index: gclient.py
|
| diff --git a/gclient.py b/gclient.py
|
| index 2d57204e07a4c268ed0ede4060324f9ae66c6d91..c01154110a34fdc88778028792cfa80ab7209abb 100644
|
| --- a/gclient.py
|
| +++ b/gclient.py
|
| @@ -503,6 +503,36 @@ solutions = [
|
| if matching_file_list:
|
| self._RunHookAction(hook_dict, matching_file_list)
|
|
|
| + def _EnforceRevisions(self, solutions):
|
| + """Checks for revision overrides."""
|
| + revision_overrides = {}
|
| + solutions = [s['name'] for s in solutions]
|
| + if self._options.revisions:
|
| + revision = self._options.revisions[0]
|
| + # Ignore solution@
|
| + rev = revision
|
| + if '@' in revision:
|
| + rev = revision.split('@', 1)[1]
|
| + revision_overrides[solutions[0]] = rev
|
| +
|
| + if len(self._options.revisions) > 1:
|
| + # Enforce solution@rev format for following params.
|
| + for revision in self._options.revisions[1:]:
|
| + if not '@' in revision:
|
| + raise gclient_utils.Error(
|
| + 'Specify the full dependency when specifying a revision number '
|
| + 'for non-primary solution.')
|
| + sol, rev = revision.split("@", 1)
|
| + # Disallow conflicting revs
|
| + if revision_overrides.get(sol, rev) != rev:
|
| + raise gclient_utils.Error(
|
| + 'Conflicting revision numbers specified for %s: %s and %s.' %
|
| + (sol, revision_overrides[sol], rev))
|
| + if not sol in solutions:
|
| + raise gclient_utils.Error('%s is not a valid solution.' % sol)
|
| + revision_overrides[sol] = rev
|
| + return revision_overrides
|
| +
|
| def RunOnDeps(self, command, args):
|
| """Runs a command on each dependency in a client and its dependencies.
|
|
|
| @@ -518,23 +548,10 @@ solutions = [
|
| if not command in self.supported_commands:
|
| raise gclient_utils.Error("'%s' is an unsupported command" % command)
|
|
|
| - # Check for revision overrides.
|
| - revision_overrides = {}
|
| - for revision in self._options.revisions:
|
| - if revision.find("@") == -1:
|
| - raise gclient_utils.Error(
|
| - "Specify the full dependency when specifying a revision number.")
|
| - revision_elem = revision.split("@")
|
| - # Disallow conflicting revs
|
| - if revision_overrides.has_key(revision_elem[0]) and \
|
| - revision_overrides[revision_elem[0]] != revision_elem[1]:
|
| - raise gclient_utils.Error(
|
| - "Conflicting revision numbers specified.")
|
| - revision_overrides[revision_elem[0]] = revision_elem[1]
|
| -
|
| solutions = self.GetVar("solutions")
|
| if not solutions:
|
| raise gclient_utils.Error("No solution specified")
|
| + revision_overrides = self._EnforceRevisions(solutions)
|
|
|
| # When running runhooks --force, there's no need to consult the SCM.
|
| # All known hooks are expected to run unconditionally regardless of working
|
| @@ -679,35 +696,13 @@ solutions = [
|
| """Output revision info mapping for the client and its dependencies.
|
|
|
| This allows the capture of an overall "revision" for the source tree that
|
| - can be used to reproduce the same tree in the future. The actual output
|
| - contains enough information (source paths, svn server urls and revisions)
|
| - that it can be used either to generate external svn/git commands (without
|
| - gclient) or as input to gclient's --rev option (with some massaging of
|
| - the data).
|
| -
|
| - Since we care about the revision of the current source tree, for git
|
| - repositories this command uses the revision of the HEAD. For subversion we
|
| - use BASE.
|
| + can be used to reproduce the same tree in the future. It is only useful for
|
| + "unpinned dependencies", i.e. DEPS/deps references without a svn revision
|
| + number or a git hash. A git branch name isn't "pinned" since the actual
|
| + commit can change.
|
|
|
| The --snapshot option allows creating a .gclient file to reproduce the tree.
|
| -
|
| - Raises:
|
| - Error: If the client has conflicting entries.
|
| """
|
| - # Check for revision overrides.
|
| - revision_overrides = {}
|
| - for revision in self._options.revisions:
|
| - if revision.find("@") < 0:
|
| - raise gclient_utils.Error(
|
| - "Specify the full dependency when specifying a revision number.")
|
| - revision_elem = revision.split("@")
|
| - # Disallow conflicting revs
|
| - if revision_overrides.has_key(revision_elem[0]) and \
|
| - revision_overrides[revision_elem[0]] != revision_elem[1]:
|
| - raise gclient_utils.Error(
|
| - "Conflicting revision numbers specified.")
|
| - revision_overrides[revision_elem[0]] = revision_elem[1]
|
| -
|
| solutions = self.GetVar("solutions")
|
| if not solutions:
|
| raise gclient_utils.Error("No solution specified")
|
| @@ -933,9 +928,10 @@ def CMDsync(parser, args):
|
| help="don't run hooks after the update is complete")
|
| parser.add_option("-r", "--revision", action="append",
|
| dest="revisions", metavar="REV", default=[],
|
| - help="update given solution to specified revision, "
|
| - "can be used multiple times for each solution, "
|
| - "e.g. -r src@123, -r internal@32")
|
| + help="Enforces revision/hash for the primary solution. "
|
| + "To modify a secondary solution, use it at least once "
|
| + "for the primary solution and then use the format "
|
| + "solution@rev/hash, e.g. -r src@123")
|
| parser.add_option("--head", action="store_true",
|
| help="skips any safesync_urls specified in "
|
| "configured solutions and sync to head instead")
|
| @@ -959,15 +955,18 @@ def CMDsync(parser, args):
|
| if not options.head:
|
| solutions = client.GetVar('solutions')
|
| if solutions:
|
| + first = True
|
| for s in solutions:
|
| - if s.get('safesync_url', ''):
|
| + if s.get('safesync_url', None):
|
| # rip through revisions and make sure we're not over-riding
|
| # something that was explicitly passed
|
| has_key = False
|
| + r_first = True
|
| for r in options.revisions:
|
| - if r.split('@')[0] == s['name']:
|
| + if (first and r_first) or r.split('@', 1)[0] == s['name']:
|
| has_key = True
|
| break
|
| + r_first = False
|
|
|
| if not has_key:
|
| handle = urllib.urlopen(s['safesync_url'])
|
| @@ -975,6 +974,7 @@ def CMDsync(parser, args):
|
| handle.close()
|
| if len(rev):
|
| options.revisions.append(s['name']+'@'+rev)
|
| + first = False
|
|
|
| if options.verbose:
|
| # Print out the .gclient file. This is longer than if we just printed the
|
|
|