Enable remotes to define their own revision

Some projects use multiple remotes.
In some cases these remotes have different naming conventions.
Add an option to define a revision in the remote configuration.

The `project` revision takes precedence over `remote` and `default`.
The `remote` revision takes precedence over `default`.
The `default` revision acts as a fall back as it originally did.

Change-Id: I2b376160d45d48b0bab840c02a3eef1a1e32cf6d
This commit is contained in:
Anthony King 2014-05-06 11:54:01 +01:00
parent 666d534636
commit 36ea2fb6ee
3 changed files with 28 additions and 9 deletions

View File

@ -35,6 +35,7 @@ following DTD:
<!ATTLIST remote alias CDATA #IMPLIED>
<!ATTLIST remote fetch CDATA #REQUIRED>
<!ATTLIST remote review CDATA #IMPLIED>
<!ATTLIST remote revision CDATA #IMPLIED>
<!ELEMENT default (EMPTY)>
<!ATTLIST default remote IDREF #IMPLIED>
@ -112,6 +113,10 @@ Attribute `review`: Hostname of the Gerrit server where reviews
are uploaded to by `repo upload`. This attribute is optional;
if not specified then `repo upload` will not function.
Attribute `revision`: Name of a Git branch (e.g. `master` or
`refs/heads/master`). Remotes with their own revision will override
the default revision.
Element default
---------------
@ -208,7 +213,8 @@ to track for this project. Names can be relative to refs/heads
(e.g. just "master") or absolute (e.g. "refs/heads/master").
Tags and/or explicit SHA-1s should work in theory, but have not
been extensively tested. If not supplied the revision given by
the default element is used.
the remote element is used if applicable, else the default
element is used.
Attribute `dest-branch`: Name of a Git branch (e.g. `master`).
When using `repo upload`, changes will be submitted for code

View File

@ -63,12 +63,14 @@ class _XmlRemote(object):
alias=None,
fetch=None,
manifestUrl=None,
review=None):
review=None,
revision=None):
self.name = name
self.fetchUrl = fetch
self.manifestUrl = manifestUrl
self.remoteAlias = alias
self.reviewUrl = review
self.revision = revision
self.resolvedFetchUrl = self._resolveFetchUrl()
def __eq__(self, other):
@ -159,6 +161,8 @@ class XmlManifest(object):
e.setAttribute('alias', r.remoteAlias)
if r.reviewUrl is not None:
e.setAttribute('review', r.reviewUrl)
if r.revision is not None:
e.setAttribute('revision', r.revision)
def Save(self, fd, peg_rev=False, peg_rev_upstream=True):
"""Write the current manifest out to the given file descriptor.
@ -240,7 +244,8 @@ class XmlManifest(object):
if d.remote:
remoteName = d.remote.remoteAlias or d.remote.name
if not d.remote or p.remote.name != remoteName:
e.setAttribute('remote', p.remote.name)
remoteName = p.remote.name
e.setAttribute('remote', remoteName)
if peg_rev:
if self.IsMirror:
value = p.bare_git.rev_parse(p.revisionExpr + '^0')
@ -252,8 +257,10 @@ class XmlManifest(object):
# isn't our value, and the if the default doesn't already have that
# covered.
e.setAttribute('upstream', p.revisionExpr)
elif not d.revisionExpr or p.revisionExpr != d.revisionExpr:
e.setAttribute('revision', p.revisionExpr)
else:
revision = self.remotes[remoteName].revision or d.revisionExpr
if not revision or revision != p.revisionExpr:
e.setAttribute('revision', p.revisionExpr)
for c in p.copyfiles:
ce = doc.createElement('copyfile')
@ -592,8 +599,11 @@ class XmlManifest(object):
review = node.getAttribute('review')
if review == '':
review = None
revision = node.getAttribute('revision')
if revision == '':
revision = None
manifestUrl = self.manifestProject.config.GetString('remote.origin.url')
return _XmlRemote(name, alias, fetch, manifestUrl, review)
return _XmlRemote(name, alias, fetch, manifestUrl, review, revision)
def _ParseDefault(self, node):
"""
@ -686,7 +696,7 @@ class XmlManifest(object):
raise ManifestParseError("no remote for project %s within %s" %
(name, self.manifestFile))
revisionExpr = node.getAttribute('revision')
revisionExpr = node.getAttribute('revision') or remote.revision
if not revisionExpr:
revisionExpr = self._default.revisionExpr
if not revisionExpr:

View File

@ -259,10 +259,12 @@ class RemoteSpec(object):
def __init__(self,
name,
url = None,
review = None):
review = None,
revision = None):
self.name = name
self.url = url
self.review = review
self.revision = revision
class RepoHook(object):
"""A RepoHook contains information about a script to run as a hook.
@ -1657,7 +1659,8 @@ class Project(object):
remote = RemoteSpec(self.remote.name,
url = url,
review = self.remote.review)
review = self.remote.review,
revision = self.remote.revision)
subproject = Project(manifest = self.manifest,
name = name,
remote = remote,