mirror of
https://gerrit.googlesource.com/git-repo
synced 2025-06-28 20:17:26 +00:00
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
5d40e26201 | |||
70939e2f73 | |||
ae6e0949d1 | |||
339ba9f6f7 | |||
70cd4ab270 |
@ -20,12 +20,16 @@ A manifest XML file (e.g. 'default.xml') roughly conforms to the
|
|||||||
following DTD:
|
following DTD:
|
||||||
|
|
||||||
<!DOCTYPE manifest [
|
<!DOCTYPE manifest [
|
||||||
<!ELEMENT manifest (remote*, default?, project*)>
|
<!ELEMENT manifest (remote*,
|
||||||
|
default?,
|
||||||
|
project*,
|
||||||
|
add-remote*)>
|
||||||
|
|
||||||
<!ELEMENT remote (EMPTY)>
|
<!ELEMENT remote (EMPTY)>
|
||||||
<!ATTLIST remote name ID #REQUIRED>
|
<!ATTLIST remote name ID #REQUIRED>
|
||||||
<!ATTLIST remote fetch CDATA #REQUIRED>
|
<!ATTLIST remote fetch CDATA #REQUIRED>
|
||||||
<!ATTLIST remote review CDATA #IMPLIED>
|
<!ATTLIST remote review CDATA #IMPLIED>
|
||||||
|
<!ATTLIST remote project-name CDATA #IMPLIED>
|
||||||
|
|
||||||
<!ELEMENT default (EMPTY)>
|
<!ELEMENT default (EMPTY)>
|
||||||
<!ATTLIST default remote IDREF #IMPLIED>
|
<!ATTLIST default remote IDREF #IMPLIED>
|
||||||
@ -36,6 +40,13 @@ following DTD:
|
|||||||
<!ATTLIST project path CDATA #IMPLIED>
|
<!ATTLIST project path CDATA #IMPLIED>
|
||||||
<!ATTLIST project remote IDREF #IMPLIED>
|
<!ATTLIST project remote IDREF #IMPLIED>
|
||||||
<!ATTLIST project revision CDATA #IMPLIED>
|
<!ATTLIST project revision CDATA #IMPLIED>
|
||||||
|
|
||||||
|
<!ELEMENT add-remote (EMPTY)>
|
||||||
|
<!ATTLIST add-remote to-project ID #REQUIRED>
|
||||||
|
<!ATTLIST add-remote name ID #REQUIRED>
|
||||||
|
<!ATTLIST add-remote fetch CDATA #REQUIRED>
|
||||||
|
<!ATTLIST add-remote review CDATA #IMPLIED>
|
||||||
|
<!ATTLIST add-remote project-name CDATA #IMPLIED>
|
||||||
]>
|
]>
|
||||||
|
|
||||||
A description of the elements and their attributes follows.
|
A description of the elements and their attributes follows.
|
||||||
@ -67,6 +78,24 @@ Attribute `review`: Hostname of the Gerrit server where reviews
|
|||||||
are uploaded to by `repo upload`. This attribute is optional;
|
are uploaded to by `repo upload`. This attribute is optional;
|
||||||
if not specified then `repo upload` will not function.
|
if not specified then `repo upload` will not function.
|
||||||
|
|
||||||
|
Attribute `project-name`: Specifies the name of this project used
|
||||||
|
by the review server given in the review attribute of this element.
|
||||||
|
Only permitted when the remote element is nested inside of a project
|
||||||
|
element (see below). If not given, defaults to the name supplied
|
||||||
|
in the project's name attribute.
|
||||||
|
|
||||||
|
Element add-remote
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Adds a remote to an existing project, whose name is given by the
|
||||||
|
to-project attribute. This is functionally equivalent to nesting
|
||||||
|
a remote element under the project, but has the advantage that it
|
||||||
|
can be specified in the uesr's `local_manifest.xml` to add a remote
|
||||||
|
to a project declared by the normal manifest.
|
||||||
|
|
||||||
|
The element can be used to add a fork of an existing project that
|
||||||
|
the user needs to work with.
|
||||||
|
|
||||||
|
|
||||||
Element default
|
Element default
|
||||||
---------------
|
---------------
|
||||||
@ -124,3 +153,32 @@ but adds an additional remote to only this project. These additional
|
|||||||
remotes are fetched from first on the initial `repo sync`, causing
|
remotes are fetched from first on the initial `repo sync`, causing
|
||||||
the majority of the project's object database to be obtained through
|
the majority of the project's object database to be obtained through
|
||||||
these additional remotes.
|
these additional remotes.
|
||||||
|
|
||||||
|
|
||||||
|
Local Manifest
|
||||||
|
==============
|
||||||
|
|
||||||
|
Additional remotes and projects may be added through a local
|
||||||
|
manifest, stored in `$TOP_DIR/.repo/local_manifest.xml`.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ cat .repo/local_manifest.xml
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<manifest>
|
||||||
|
<project path="manifest"
|
||||||
|
name="tools/manifest" />
|
||||||
|
<project path="platform-manifest"
|
||||||
|
name="platform/manifest" />
|
||||||
|
</manifest>
|
||||||
|
----
|
||||||
|
|
||||||
|
Users may add projects to the local manifest prior to a `repo sync`
|
||||||
|
invocation, instructing repo to automatically download and manage
|
||||||
|
these extra projects.
|
||||||
|
|
||||||
|
Currently the only supported feature of a local manifest is to
|
||||||
|
add new remotes and/or projects. In the future a local manifest
|
||||||
|
may support picking different revisions of a project, or deleting
|
||||||
|
projects specified in the default manifest.
|
||||||
|
@ -258,6 +258,7 @@ class Remote(object):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.url = self._Get('url')
|
self.url = self._Get('url')
|
||||||
self.review = self._Get('review')
|
self.review = self._Get('review')
|
||||||
|
self.projectname = self._Get('projectname')
|
||||||
self.fetch = map(lambda x: RefSpec.FromString(x),
|
self.fetch = map(lambda x: RefSpec.FromString(x),
|
||||||
self._Get('fetch', all=True))
|
self._Get('fetch', all=True))
|
||||||
|
|
||||||
@ -299,6 +300,7 @@ class Remote(object):
|
|||||||
"""
|
"""
|
||||||
self._Set('url', self.url)
|
self._Set('url', self.url)
|
||||||
self._Set('review', self.review)
|
self._Set('review', self.review)
|
||||||
|
self._Set('projectname', self.projectname)
|
||||||
self._Set('fetch', map(lambda x: str(x), self.fetch))
|
self._Set('fetch', map(lambda x: str(x), self.fetch))
|
||||||
|
|
||||||
def _Set(self, key, value):
|
def _Set(self, key, value):
|
||||||
|
32
manifest.py
32
manifest.py
@ -165,6 +165,16 @@ class Manifest(object):
|
|||||||
(project.name, self.manifestFile)
|
(project.name, self.manifestFile)
|
||||||
self._projects[project.name] = project
|
self._projects[project.name] = project
|
||||||
|
|
||||||
|
for node in config.childNodes:
|
||||||
|
if node.nodeName == 'add-remote':
|
||||||
|
pn = self._reqatt(node, 'to-project')
|
||||||
|
project = self._projects.get(pn)
|
||||||
|
if not project:
|
||||||
|
raise ManifestParseError, \
|
||||||
|
'project %s not defined in %s' % \
|
||||||
|
(pn, self.manifestFile)
|
||||||
|
self._ParseProjectExtraRemote(project, node)
|
||||||
|
|
||||||
def _AddMetaProjectMirror(self, m):
|
def _AddMetaProjectMirror(self, m):
|
||||||
name = None
|
name = None
|
||||||
m_url = m.GetRemote(m.remote.name).url
|
m_url = m.GetRemote(m.remote.name).url
|
||||||
@ -206,10 +216,17 @@ class Manifest(object):
|
|||||||
name = self._reqatt(node, 'name')
|
name = self._reqatt(node, 'name')
|
||||||
fetch = self._reqatt(node, 'fetch')
|
fetch = self._reqatt(node, 'fetch')
|
||||||
review = node.getAttribute('review')
|
review = node.getAttribute('review')
|
||||||
|
if review == '':
|
||||||
|
review = None
|
||||||
|
|
||||||
|
projectName = node.getAttribute('project-name')
|
||||||
|
if projectName == '':
|
||||||
|
projectName = None
|
||||||
|
|
||||||
r = Remote(name=name,
|
r = Remote(name=name,
|
||||||
fetch=fetch,
|
fetch=fetch,
|
||||||
review=review)
|
review=review,
|
||||||
|
projectName=projectName)
|
||||||
|
|
||||||
for n in node.childNodes:
|
for n in node.childNodes:
|
||||||
if n.nodeName == 'require':
|
if n.nodeName == 'require':
|
||||||
@ -224,6 +241,8 @@ class Manifest(object):
|
|||||||
d = _Default()
|
d = _Default()
|
||||||
d.remote = self._get_remote(node)
|
d.remote = self._get_remote(node)
|
||||||
d.revision = node.getAttribute('revision')
|
d.revision = node.getAttribute('revision')
|
||||||
|
if d.revision == '':
|
||||||
|
d.revision = None
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def _ParseProject(self, node):
|
def _ParseProject(self, node):
|
||||||
@ -274,6 +293,13 @@ class Manifest(object):
|
|||||||
|
|
||||||
for n in node.childNodes:
|
for n in node.childNodes:
|
||||||
if n.nodeName == 'remote':
|
if n.nodeName == 'remote':
|
||||||
|
self._ParseProjectExtraRemote(project, n)
|
||||||
|
elif n.nodeName == 'copyfile':
|
||||||
|
self._ParseCopyFile(project, n)
|
||||||
|
|
||||||
|
return project
|
||||||
|
|
||||||
|
def _ParseProjectExtraRemote(self, project, n):
|
||||||
r = self._ParseRemote(n)
|
r = self._ParseRemote(n)
|
||||||
if project.extraRemotes.get(r.name) \
|
if project.extraRemotes.get(r.name) \
|
||||||
or project.remote.name == r.name:
|
or project.remote.name == r.name:
|
||||||
@ -281,10 +307,6 @@ class Manifest(object):
|
|||||||
'duplicate remote %s in project %s in %s' % \
|
'duplicate remote %s in project %s in %s' % \
|
||||||
(r.name, project.name, self.manifestFile)
|
(r.name, project.name, self.manifestFile)
|
||||||
project.extraRemotes[r.name] = r
|
project.extraRemotes[r.name] = r
|
||||||
elif n.nodeName == 'copyfile':
|
|
||||||
self._ParseCopyFile(project, n)
|
|
||||||
|
|
||||||
return project
|
|
||||||
|
|
||||||
def _ParseCopyFile(self, project, node):
|
def _ParseCopyFile(self, project, node):
|
||||||
src = self._reqatt(node, 'src')
|
src = self._reqatt(node, 'src')
|
||||||
|
12
project.py
12
project.py
@ -461,13 +461,17 @@ class Project(object):
|
|||||||
if not base_list:
|
if not base_list:
|
||||||
raise GitError('no base refs, cannot upload %s' % branch.name)
|
raise GitError('no base refs, cannot upload %s' % branch.name)
|
||||||
|
|
||||||
|
if not branch.remote.projectname:
|
||||||
|
branch.remote.projectname = self.name
|
||||||
|
branch.remote.Save()
|
||||||
|
|
||||||
print >>sys.stderr, ''
|
print >>sys.stderr, ''
|
||||||
_info("Uploading %s to %s:", branch.name, self.name)
|
_info("Uploading %s to %s:", branch.name, self.name)
|
||||||
try:
|
try:
|
||||||
UploadBundle(project = self,
|
UploadBundle(project = self,
|
||||||
server = branch.remote.review,
|
server = branch.remote.review,
|
||||||
email = self.UserEmail,
|
email = self.UserEmail,
|
||||||
dest_project = self.name,
|
dest_project = branch.remote.projectname,
|
||||||
dest_branch = dest_branch,
|
dest_branch = dest_branch,
|
||||||
src_branch = R_HEADS + branch.name,
|
src_branch = R_HEADS + branch.name,
|
||||||
bases = base_list)
|
bases = base_list)
|
||||||
@ -887,6 +891,8 @@ class Project(object):
|
|||||||
url += '/%s.git' % self.name
|
url += '/%s.git' % self.name
|
||||||
remote.url = url
|
remote.url = url
|
||||||
remote.review = self.remote.reviewUrl
|
remote.review = self.remote.reviewUrl
|
||||||
|
if remote.projectname is None:
|
||||||
|
remote.projectname = self.name
|
||||||
|
|
||||||
if self.worktree:
|
if self.worktree:
|
||||||
remote.ResetFetch(mirror=False)
|
remote.ResetFetch(mirror=False)
|
||||||
@ -898,6 +904,10 @@ class Project(object):
|
|||||||
remote = self.GetRemote(r.name)
|
remote = self.GetRemote(r.name)
|
||||||
remote.url = r.fetchUrl
|
remote.url = r.fetchUrl
|
||||||
remote.review = r.reviewUrl
|
remote.review = r.reviewUrl
|
||||||
|
if r.projectName:
|
||||||
|
remote.projectname = r.projectName
|
||||||
|
elif remote.projectname is None:
|
||||||
|
remote.projectname = self.name
|
||||||
remote.ResetFetch()
|
remote.ResetFetch()
|
||||||
remote.Save()
|
remote.Save()
|
||||||
|
|
||||||
|
@ -14,8 +14,12 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
class Remote(object):
|
class Remote(object):
|
||||||
def __init__(self, name, fetch=None, review=None):
|
def __init__(self, name,
|
||||||
|
fetch=None,
|
||||||
|
review=None,
|
||||||
|
projectName=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.fetchUrl = fetch
|
self.fetchUrl = fetch
|
||||||
self.reviewUrl = review
|
self.reviewUrl = review
|
||||||
|
self.projectName = projectName
|
||||||
self.requiredCommits = []
|
self.requiredCommits = []
|
||||||
|
Reference in New Issue
Block a user