diff options
| -rw-r--r-- | .project | 2 | ||||
| -rw-r--r-- | .pydevproject | 2 | ||||
| -rw-r--r-- | .pylintrc | 2 | ||||
| -rw-r--r-- | command.py | 15 | ||||
| -rw-r--r-- | docs/manifest-format.txt | 12 | ||||
| -rw-r--r-- | git_config.py | 17 | ||||
| -rw-r--r-- | git_refs.py | 9 | ||||
| -rwxr-xr-x | main.py | 7 | ||||
| -rw-r--r-- | manifest_xml.py | 81 | ||||
| -rw-r--r-- | project.py | 69 | ||||
| -rwxr-xr-x | repo | 17 | ||||
| -rw-r--r-- | subcmds/__init__.py | 4 | ||||
| -rw-r--r-- | subcmds/branches.py | 5 | ||||
| -rw-r--r-- | subcmds/forall.py | 14 | ||||
| -rw-r--r-- | subcmds/help.py | 10 | ||||
| -rw-r--r-- | subcmds/info.py | 2 | ||||
| -rw-r--r-- | subcmds/init.py | 7 | ||||
| -rw-r--r-- | subcmds/list.py | 31 | ||||
| -rw-r--r-- | subcmds/overview.py | 2 | ||||
| -rw-r--r-- | subcmds/stage.py | 8 | ||||
| -rw-r--r-- | subcmds/status.py | 11 | ||||
| -rw-r--r-- | subcmds/sync.py | 47 | ||||
| -rw-r--r-- | subcmds/upload.py | 7 |
23 files changed, 257 insertions, 124 deletions
| @@ -1,6 +1,6 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | <projectDescription> | 2 | <projectDescription> |
| 3 | <name>repo</name> | 3 | <name>git-repo</name> |
| 4 | <comment></comment> | 4 | <comment></comment> |
| 5 | <projects> | 5 | <projects> |
| 6 | </projects> | 6 | </projects> |
diff --git a/.pydevproject b/.pydevproject index 880abd62..27c2485a 100644 --- a/.pydevproject +++ b/.pydevproject | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | <pydev_project> | 4 | <pydev_project> |
| 5 | <pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH"> | 5 | <pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH"> |
| 6 | <path>/repo</path> | 6 | <path>/git-repo</path> |
| 7 | </pydev_pathproperty> | 7 | </pydev_pathproperty> |
| 8 | <pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property> | 8 | <pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property> |
| 9 | <pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property> | 9 | <pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property> |
| @@ -53,7 +53,7 @@ load-plugins= | |||
| 53 | enable=RP0004 | 53 | enable=RP0004 |
| 54 | 54 | ||
| 55 | # Disable the message(s) with the given id(s). | 55 | # Disable the message(s) with the given id(s). |
| 56 | disable=R0903,R0912,R0913,R0914,R0915,W0141,C0111,C0103,W0603,W0703,R0911,C0301,C0302,R0902,R0904,W0142,W0212,E1101,E1103,R0201,W0201,W0122,W0232,RP0001,RP0003,RP0101,RP0002,RP0401,RP0701,RP0801 | 56 | disable=R0903,R0912,R0913,R0914,R0915,W0141,C0111,C0103,W0603,W0703,R0911,C0301,C0302,R0902,R0904,W0142,W0212,E1101,E1103,R0201,W0201,W0122,W0232,RP0001,RP0003,RP0101,RP0002,RP0401,RP0701,RP0801,F0401,E0611,R0801 |
| 57 | 57 | ||
| 58 | [REPORTS] | 58 | [REPORTS] |
| 59 | 59 | ||
| @@ -136,11 +136,11 @@ class Command(object): | |||
| 136 | 136 | ||
| 137 | groups = mp.config.GetString('manifest.groups') | 137 | groups = mp.config.GetString('manifest.groups') |
| 138 | if not groups: | 138 | if not groups: |
| 139 | groups = 'all,-notdefault,platform-' + platform.system().lower() | 139 | groups = 'default,platform-' + platform.system().lower() |
| 140 | groups = [x for x in re.split(r'[,\s]+', groups) if x] | 140 | groups = [x for x in re.split(r'[,\s]+', groups) if x] |
| 141 | 141 | ||
| 142 | if not args: | 142 | if not args: |
| 143 | all_projects_list = all_projects.values() | 143 | all_projects_list = list(all_projects.values()) |
| 144 | derived_projects = {} | 144 | derived_projects = {} |
| 145 | for project in all_projects_list: | 145 | for project in all_projects_list: |
| 146 | if submodules_ok or project.sync_s: | 146 | if submodules_ok or project.sync_s: |
| @@ -186,6 +186,17 @@ class Command(object): | |||
| 186 | result.sort(key=_getpath) | 186 | result.sort(key=_getpath) |
| 187 | return result | 187 | return result |
| 188 | 188 | ||
| 189 | def FindProjects(self, args): | ||
| 190 | result = [] | ||
| 191 | patterns = [re.compile(r'%s' % a, re.IGNORECASE) for a in args] | ||
| 192 | for project in self.GetProjects(''): | ||
| 193 | for pattern in patterns: | ||
| 194 | if pattern.search(project.name) or pattern.search(project.relpath): | ||
| 195 | result.append(project) | ||
| 196 | break | ||
| 197 | result.sort(key=lambda project: project.relpath) | ||
| 198 | return result | ||
| 199 | |||
| 189 | # pylint: disable=W0223 | 200 | # pylint: disable=W0223 |
| 190 | # Pylint warns that the `InteractiveCommand` and `PagedCommand` classes do not | 201 | # Pylint warns that the `InteractiveCommand` and `PagedCommand` classes do not |
| 191 | # override method `Execute` which is abstract in `Command`. Since that method | 202 | # override method `Execute` which is abstract in `Command`. Since that method |
diff --git a/docs/manifest-format.txt b/docs/manifest-format.txt index 0bf09f6f..59f6a2fd 100644 --- a/docs/manifest-format.txt +++ b/docs/manifest-format.txt | |||
| @@ -56,6 +56,8 @@ following DTD: | |||
| 56 | <!ATTLIST project sync-c CDATA #IMPLIED> | 56 | <!ATTLIST project sync-c CDATA #IMPLIED> |
| 57 | <!ATTLIST project sync-s CDATA #IMPLIED> | 57 | <!ATTLIST project sync-s CDATA #IMPLIED> |
| 58 | <!ATTLIST project upstream CDATA #IMPLIED> | 58 | <!ATTLIST project upstream CDATA #IMPLIED> |
| 59 | <!ATTLIST project clone-depth CDATA #IMPLIED> | ||
| 60 | <!ATTLIST project force-path CDATA #IMPLIED> | ||
| 59 | 61 | ||
| 60 | <!ELEMENT annotation (EMPTY)> | 62 | <!ELEMENT annotation (EMPTY)> |
| 61 | <!ATTLIST annotation name CDATA #REQUIRED> | 63 | <!ATTLIST annotation name CDATA #REQUIRED> |
| @@ -222,6 +224,16 @@ Attribute `upstream`: Name of the Git branch in which a sha1 | |||
| 222 | can be found. Used when syncing a revision locked manifest in | 224 | can be found. Used when syncing a revision locked manifest in |
| 223 | -c mode to avoid having to sync the entire ref space. | 225 | -c mode to avoid having to sync the entire ref space. |
| 224 | 226 | ||
| 227 | Attribute `clone-depth`: Set the depth to use when fetching this | ||
| 228 | project. If specified, this value will override any value given | ||
| 229 | to repo init with the --depth option on the command line. | ||
| 230 | |||
| 231 | Attribute `force-path`: Set to true to force this project to create the | ||
| 232 | local mirror repository according to its `path` attribute (if supplied) | ||
| 233 | rather than the `name` attribute. This attribute only applies to the | ||
| 234 | local mirrors syncing, it will be ignored when syncing the projects in a | ||
| 235 | client working directory. | ||
| 236 | |||
| 225 | Element annotation | 237 | Element annotation |
| 226 | ------------------ | 238 | ------------------ |
| 227 | 239 | ||
diff --git a/git_config.py b/git_config.py index 56cc6a24..9524df9b 100644 --- a/git_config.py +++ b/git_config.py | |||
| @@ -14,8 +14,9 @@ | |||
| 14 | # limitations under the License. | 14 | # limitations under the License. |
| 15 | 15 | ||
| 16 | from __future__ import print_function | 16 | from __future__ import print_function |
| 17 | import cPickle | 17 | |
| 18 | import os | 18 | import os |
| 19 | import pickle | ||
| 19 | import re | 20 | import re |
| 20 | import subprocess | 21 | import subprocess |
| 21 | import sys | 22 | import sys |
| @@ -262,7 +263,7 @@ class GitConfig(object): | |||
| 262 | Trace(': unpickle %s', self.file) | 263 | Trace(': unpickle %s', self.file) |
| 263 | fd = open(self._pickle, 'rb') | 264 | fd = open(self._pickle, 'rb') |
| 264 | try: | 265 | try: |
| 265 | return cPickle.load(fd) | 266 | return pickle.load(fd) |
| 266 | finally: | 267 | finally: |
| 267 | fd.close() | 268 | fd.close() |
| 268 | except EOFError: | 269 | except EOFError: |
| @@ -271,7 +272,7 @@ class GitConfig(object): | |||
| 271 | except IOError: | 272 | except IOError: |
| 272 | os.remove(self._pickle) | 273 | os.remove(self._pickle) |
| 273 | return None | 274 | return None |
| 274 | except cPickle.PickleError: | 275 | except pickle.PickleError: |
| 275 | os.remove(self._pickle) | 276 | os.remove(self._pickle) |
| 276 | return None | 277 | return None |
| 277 | 278 | ||
| @@ -279,13 +280,13 @@ class GitConfig(object): | |||
| 279 | try: | 280 | try: |
| 280 | fd = open(self._pickle, 'wb') | 281 | fd = open(self._pickle, 'wb') |
| 281 | try: | 282 | try: |
| 282 | cPickle.dump(cache, fd, cPickle.HIGHEST_PROTOCOL) | 283 | pickle.dump(cache, fd, pickle.HIGHEST_PROTOCOL) |
| 283 | finally: | 284 | finally: |
| 284 | fd.close() | 285 | fd.close() |
| 285 | except IOError: | 286 | except IOError: |
| 286 | if os.path.exists(self._pickle): | 287 | if os.path.exists(self._pickle): |
| 287 | os.remove(self._pickle) | 288 | os.remove(self._pickle) |
| 288 | except cPickle.PickleError: | 289 | except pickle.PickleError: |
| 289 | if os.path.exists(self._pickle): | 290 | if os.path.exists(self._pickle): |
| 290 | os.remove(self._pickle) | 291 | os.remove(self._pickle) |
| 291 | 292 | ||
| @@ -537,8 +538,8 @@ class Remote(object): | |||
| 537 | self.url = self._Get('url') | 538 | self.url = self._Get('url') |
| 538 | self.review = self._Get('review') | 539 | self.review = self._Get('review') |
| 539 | self.projectname = self._Get('projectname') | 540 | self.projectname = self._Get('projectname') |
| 540 | self.fetch = map(RefSpec.FromString, | 541 | self.fetch = list(map(RefSpec.FromString, |
| 541 | self._Get('fetch', all_keys=True)) | 542 | self._Get('fetch', all_keys=True))) |
| 542 | self._review_url = None | 543 | self._review_url = None |
| 543 | 544 | ||
| 544 | def _InsteadOf(self): | 545 | def _InsteadOf(self): |
| @@ -657,7 +658,7 @@ class Remote(object): | |||
| 657 | self._Set('url', self.url) | 658 | self._Set('url', self.url) |
| 658 | self._Set('review', self.review) | 659 | self._Set('review', self.review) |
| 659 | self._Set('projectname', self.projectname) | 660 | self._Set('projectname', self.projectname) |
| 660 | self._Set('fetch', map(str, self.fetch)) | 661 | self._Set('fetch', list(map(str, self.fetch))) |
| 661 | 662 | ||
| 662 | def _Set(self, key, value): | 663 | def _Set(self, key, value): |
| 663 | key = 'remote.%s.%s' % (self.name, key) | 664 | key = 'remote.%s.%s' % (self.name, key) |
diff --git a/git_refs.py b/git_refs.py index cfeffba9..4dd68769 100644 --- a/git_refs.py +++ b/git_refs.py | |||
| @@ -66,7 +66,7 @@ class GitRefs(object): | |||
| 66 | def _NeedUpdate(self): | 66 | def _NeedUpdate(self): |
| 67 | Trace(': scan refs %s', self._gitdir) | 67 | Trace(': scan refs %s', self._gitdir) |
| 68 | 68 | ||
| 69 | for name, mtime in self._mtime.iteritems(): | 69 | for name, mtime in self._mtime.items(): |
| 70 | try: | 70 | try: |
| 71 | if mtime != os.path.getmtime(os.path.join(self._gitdir, name)): | 71 | if mtime != os.path.getmtime(os.path.join(self._gitdir, name)): |
| 72 | return True | 72 | return True |
| @@ -89,7 +89,7 @@ class GitRefs(object): | |||
| 89 | attempts = 0 | 89 | attempts = 0 |
| 90 | while scan and attempts < 5: | 90 | while scan and attempts < 5: |
| 91 | scan_next = {} | 91 | scan_next = {} |
| 92 | for name, dest in scan.iteritems(): | 92 | for name, dest in scan.items(): |
| 93 | if dest in self._phyref: | 93 | if dest in self._phyref: |
| 94 | self._phyref[name] = self._phyref[dest] | 94 | self._phyref[name] = self._phyref[dest] |
| 95 | else: | 95 | else: |
| @@ -108,6 +108,7 @@ class GitRefs(object): | |||
| 108 | return | 108 | return |
| 109 | try: | 109 | try: |
| 110 | for line in fd: | 110 | for line in fd: |
| 111 | line = str(line) | ||
| 111 | if line[0] == '#': | 112 | if line[0] == '#': |
| 112 | continue | 113 | continue |
| 113 | if line[0] == '^': | 114 | if line[0] == '^': |
| @@ -150,6 +151,10 @@ class GitRefs(object): | |||
| 150 | finally: | 151 | finally: |
| 151 | fd.close() | 152 | fd.close() |
| 152 | 153 | ||
| 154 | try: | ||
| 155 | ref_id = ref_id.decode() | ||
| 156 | except AttributeError: | ||
| 157 | pass | ||
| 153 | if not ref_id: | 158 | if not ref_id: |
| 154 | return | 159 | return |
| 155 | ref_id = ref_id[:-1] | 160 | ref_id = ref_id[:-1] |
| @@ -50,6 +50,11 @@ from pager import RunPager | |||
| 50 | 50 | ||
| 51 | from subcmds import all_commands | 51 | from subcmds import all_commands |
| 52 | 52 | ||
| 53 | try: | ||
| 54 | input = raw_input | ||
| 55 | except NameError: | ||
| 56 | pass | ||
| 57 | |||
| 53 | global_options = optparse.OptionParser( | 58 | global_options = optparse.OptionParser( |
| 54 | usage="repo [-p|--paginate|--no-pager] COMMAND [ARGS]" | 59 | usage="repo [-p|--paginate|--no-pager] COMMAND [ARGS]" |
| 55 | ) | 60 | ) |
| @@ -286,7 +291,7 @@ def _AddPasswordFromUserInput(handler, msg, req): | |||
| 286 | if user is None: | 291 | if user is None: |
| 287 | print(msg) | 292 | print(msg) |
| 288 | try: | 293 | try: |
| 289 | user = raw_input('User: ') | 294 | user = input('User: ') |
| 290 | password = getpass.getpass() | 295 | password = getpass.getpass() |
| 291 | except KeyboardInterrupt: | 296 | except KeyboardInterrupt: |
| 292 | return | 297 | return |
diff --git a/manifest_xml.py b/manifest_xml.py index 50417c60..cc441dc8 100644 --- a/manifest_xml.py +++ b/manifest_xml.py | |||
| @@ -18,7 +18,15 @@ import itertools | |||
| 18 | import os | 18 | import os |
| 19 | import re | 19 | import re |
| 20 | import sys | 20 | import sys |
| 21 | import urlparse | 21 | try: |
| 22 | # For python3 | ||
| 23 | import urllib.parse | ||
| 24 | except ImportError: | ||
| 25 | # For python2 | ||
| 26 | import imp | ||
| 27 | import urlparse | ||
| 28 | urllib = imp.new_module('urllib') | ||
| 29 | urllib.parse = urlparse | ||
| 22 | import xml.dom.minidom | 30 | import xml.dom.minidom |
| 23 | 31 | ||
| 24 | from git_config import GitConfig | 32 | from git_config import GitConfig |
| @@ -30,8 +38,8 @@ MANIFEST_FILE_NAME = 'manifest.xml' | |||
| 30 | LOCAL_MANIFEST_NAME = 'local_manifest.xml' | 38 | LOCAL_MANIFEST_NAME = 'local_manifest.xml' |
| 31 | LOCAL_MANIFESTS_DIR_NAME = 'local_manifests' | 39 | LOCAL_MANIFESTS_DIR_NAME = 'local_manifests' |
| 32 | 40 | ||
| 33 | urlparse.uses_relative.extend(['ssh', 'git']) | 41 | urllib.parse.uses_relative.extend(['ssh', 'git']) |
| 34 | urlparse.uses_netloc.extend(['ssh', 'git']) | 42 | urllib.parse.uses_netloc.extend(['ssh', 'git']) |
| 35 | 43 | ||
| 36 | class _Default(object): | 44 | class _Default(object): |
| 37 | """Project defaults within the manifest.""" | 45 | """Project defaults within the manifest.""" |
| @@ -73,7 +81,7 @@ class _XmlRemote(object): | |||
| 73 | # ie, if manifestUrl is of the form <hostname:port> | 81 | # ie, if manifestUrl is of the form <hostname:port> |
| 74 | if manifestUrl.find(':') != manifestUrl.find('/') - 1: | 82 | if manifestUrl.find(':') != manifestUrl.find('/') - 1: |
| 75 | manifestUrl = 'gopher://' + manifestUrl | 83 | manifestUrl = 'gopher://' + manifestUrl |
| 76 | url = urlparse.urljoin(manifestUrl, url) | 84 | url = urllib.parse.urljoin(manifestUrl, url) |
| 77 | url = re.sub(r'^gopher://', '', url) | 85 | url = re.sub(r'^gopher://', '', url) |
| 78 | if p: | 86 | if p: |
| 79 | url = 'persistent-' + url | 87 | url = 'persistent-' + url |
| @@ -82,8 +90,6 @@ class _XmlRemote(object): | |||
| 82 | def ToRemoteSpec(self, projectName): | 90 | def ToRemoteSpec(self, projectName): |
| 83 | url = self.resolvedFetchUrl.rstrip('/') + '/' + projectName | 91 | url = self.resolvedFetchUrl.rstrip('/') + '/' + projectName |
| 84 | remoteName = self.name | 92 | remoteName = self.name |
| 85 | if self.remoteAlias: | ||
| 86 | remoteName = self.remoteAlias | ||
| 87 | return RemoteSpec(remoteName, url, self.reviewUrl) | 93 | return RemoteSpec(remoteName, url, self.reviewUrl) |
| 88 | 94 | ||
| 89 | class XmlManifest(object): | 95 | class XmlManifest(object): |
| @@ -164,10 +170,8 @@ class XmlManifest(object): | |||
| 164 | notice_element.appendChild(doc.createTextNode(indented_notice)) | 170 | notice_element.appendChild(doc.createTextNode(indented_notice)) |
| 165 | 171 | ||
| 166 | d = self.default | 172 | d = self.default |
| 167 | sort_remotes = list(self.remotes.keys()) | ||
| 168 | sort_remotes.sort() | ||
| 169 | 173 | ||
| 170 | for r in sort_remotes: | 174 | for r in sorted(self.remotes): |
| 171 | self._RemoteToXml(self.remotes[r], doc, root) | 175 | self._RemoteToXml(self.remotes[r], doc, root) |
| 172 | if self.remotes: | 176 | if self.remotes: |
| 173 | root.appendChild(doc.createTextNode('')) | 177 | root.appendChild(doc.createTextNode('')) |
| @@ -259,12 +263,11 @@ class XmlManifest(object): | |||
| 259 | e.setAttribute('sync-s', 'true') | 263 | e.setAttribute('sync-s', 'true') |
| 260 | 264 | ||
| 261 | if p.subprojects: | 265 | if p.subprojects: |
| 262 | sort_projects = [subp.name for subp in p.subprojects] | 266 | sort_projects = list(sorted([subp.name for subp in p.subprojects])) |
| 263 | sort_projects.sort() | ||
| 264 | output_projects(p, e, sort_projects) | 267 | output_projects(p, e, sort_projects) |
| 265 | 268 | ||
| 266 | sort_projects = [key for key in self.projects.keys() | 269 | sort_projects = list(sorted([key for key, value in self.projects.items() |
| 267 | if not self.projects[key].parent] | 270 | if not value.parent])) |
| 268 | sort_projects.sort() | 271 | sort_projects.sort() |
| 269 | output_projects(None, root, sort_projects) | 272 | output_projects(None, root, sort_projects) |
| 270 | 273 | ||
| @@ -388,9 +391,8 @@ class XmlManifest(object): | |||
| 388 | name = self._reqatt(node, 'name') | 391 | name = self._reqatt(node, 'name') |
| 389 | fp = os.path.join(include_root, name) | 392 | fp = os.path.join(include_root, name) |
| 390 | if not os.path.isfile(fp): | 393 | if not os.path.isfile(fp): |
| 391 | raise ManifestParseError, \ | 394 | raise ManifestParseError("include %s doesn't exist or isn't a file" |
| 392 | "include %s doesn't exist or isn't a file" % \ | 395 | % (name,)) |
| 393 | (name,) | ||
| 394 | try: | 396 | try: |
| 395 | nodes.extend(self._ParseManifestXml(fp, include_root)) | 397 | nodes.extend(self._ParseManifestXml(fp, include_root)) |
| 396 | # should isolate this to the exact exception, but that's | 398 | # should isolate this to the exact exception, but that's |
| @@ -496,7 +498,7 @@ class XmlManifest(object): | |||
| 496 | name = None | 498 | name = None |
| 497 | m_url = m.GetRemote(m.remote.name).url | 499 | m_url = m.GetRemote(m.remote.name).url |
| 498 | if m_url.endswith('/.git'): | 500 | if m_url.endswith('/.git'): |
| 499 | raise ManifestParseError, 'refusing to mirror %s' % m_url | 501 | raise ManifestParseError('refusing to mirror %s' % m_url) |
| 500 | 502 | ||
| 501 | if self._default and self._default.remote: | 503 | if self._default and self._default.remote: |
| 502 | url = self._default.remote.resolvedFetchUrl | 504 | url = self._default.remote.resolvedFetchUrl |
| @@ -590,7 +592,7 @@ class XmlManifest(object): | |||
| 590 | 592 | ||
| 591 | # Figure out minimum indentation, skipping the first line (the same line | 593 | # Figure out minimum indentation, skipping the first line (the same line |
| 592 | # as the <notice> tag)... | 594 | # as the <notice> tag)... |
| 593 | minIndent = sys.maxint | 595 | minIndent = sys.maxsize |
| 594 | lines = notice.splitlines() | 596 | lines = notice.splitlines() |
| 595 | for line in lines[1:]: | 597 | for line in lines[1:]: |
| 596 | lstrippedLine = line.lstrip() | 598 | lstrippedLine = line.lstrip() |
| @@ -629,25 +631,22 @@ class XmlManifest(object): | |||
| 629 | if remote is None: | 631 | if remote is None: |
| 630 | remote = self._default.remote | 632 | remote = self._default.remote |
| 631 | if remote is None: | 633 | if remote is None: |
| 632 | raise ManifestParseError, \ | 634 | raise ManifestParseError("no remote for project %s within %s" % |
| 633 | "no remote for project %s within %s" % \ | 635 | (name, self.manifestFile)) |
| 634 | (name, self.manifestFile) | ||
| 635 | 636 | ||
| 636 | revisionExpr = node.getAttribute('revision') | 637 | revisionExpr = node.getAttribute('revision') |
| 637 | if not revisionExpr: | 638 | if not revisionExpr: |
| 638 | revisionExpr = self._default.revisionExpr | 639 | revisionExpr = self._default.revisionExpr |
| 639 | if not revisionExpr: | 640 | if not revisionExpr: |
| 640 | raise ManifestParseError, \ | 641 | raise ManifestParseError("no revision for project %s within %s" % |
| 641 | "no revision for project %s within %s" % \ | 642 | (name, self.manifestFile)) |
| 642 | (name, self.manifestFile) | ||
| 643 | 643 | ||
| 644 | path = node.getAttribute('path') | 644 | path = node.getAttribute('path') |
| 645 | if not path: | 645 | if not path: |
| 646 | path = name | 646 | path = name |
| 647 | if path.startswith('/'): | 647 | if path.startswith('/'): |
| 648 | raise ManifestParseError, \ | 648 | raise ManifestParseError("project %s path cannot be absolute in %s" % |
| 649 | "project %s path cannot be absolute in %s" % \ | 649 | (name, self.manifestFile)) |
| 650 | (name, self.manifestFile) | ||
| 651 | 650 | ||
| 652 | rebase = node.getAttribute('rebase') | 651 | rebase = node.getAttribute('rebase') |
| 653 | if not rebase: | 652 | if not rebase: |
| @@ -667,6 +666,16 @@ class XmlManifest(object): | |||
| 667 | else: | 666 | else: |
| 668 | sync_s = sync_s.lower() in ("yes", "true", "1") | 667 | sync_s = sync_s.lower() in ("yes", "true", "1") |
| 669 | 668 | ||
| 669 | clone_depth = node.getAttribute('clone-depth') | ||
| 670 | if clone_depth: | ||
| 671 | try: | ||
| 672 | clone_depth = int(clone_depth) | ||
| 673 | if clone_depth <= 0: | ||
| 674 | raise ValueError() | ||
| 675 | except ValueError: | ||
| 676 | raise ManifestParseError('invalid clone-depth %s in %s' % | ||
| 677 | (clone_depth, self.manifestFile)) | ||
| 678 | |||
| 670 | upstream = node.getAttribute('upstream') | 679 | upstream = node.getAttribute('upstream') |
| 671 | 680 | ||
| 672 | groups = '' | 681 | groups = '' |
| @@ -682,6 +691,10 @@ class XmlManifest(object): | |||
| 682 | default_groups = ['all', 'name:%s' % name, 'path:%s' % relpath] | 691 | default_groups = ['all', 'name:%s' % name, 'path:%s' % relpath] |
| 683 | groups.extend(set(default_groups).difference(groups)) | 692 | groups.extend(set(default_groups).difference(groups)) |
| 684 | 693 | ||
| 694 | if self.IsMirror and node.hasAttribute('force-path'): | ||
| 695 | if node.getAttribute('force-path').lower() in ("yes", "true", "1"): | ||
| 696 | gitdir = os.path.join(self.topdir, '%s.git' % path) | ||
| 697 | |||
| 685 | project = Project(manifest = self, | 698 | project = Project(manifest = self, |
| 686 | name = name, | 699 | name = name, |
| 687 | remote = remote.ToRemoteSpec(name), | 700 | remote = remote.ToRemoteSpec(name), |
| @@ -694,6 +707,7 @@ class XmlManifest(object): | |||
| 694 | groups = groups, | 707 | groups = groups, |
| 695 | sync_c = sync_c, | 708 | sync_c = sync_c, |
| 696 | sync_s = sync_s, | 709 | sync_s = sync_s, |
| 710 | clone_depth = clone_depth, | ||
| 697 | upstream = upstream, | 711 | upstream = upstream, |
| 698 | parent = parent) | 712 | parent = parent) |
| 699 | 713 | ||
| @@ -751,7 +765,8 @@ class XmlManifest(object): | |||
| 751 | except ManifestParseError: | 765 | except ManifestParseError: |
| 752 | keep = "true" | 766 | keep = "true" |
| 753 | if keep != "true" and keep != "false": | 767 | if keep != "true" and keep != "false": |
| 754 | raise ManifestParseError, "optional \"keep\" attribute must be \"true\" or \"false\"" | 768 | raise ManifestParseError('optional "keep" attribute must be ' |
| 769 | '"true" or "false"') | ||
| 755 | project.AddAnnotation(name, value, keep) | 770 | project.AddAnnotation(name, value, keep) |
| 756 | 771 | ||
| 757 | def _get_remote(self, node): | 772 | def _get_remote(self, node): |
| @@ -761,9 +776,8 @@ class XmlManifest(object): | |||
| 761 | 776 | ||
| 762 | v = self._remotes.get(name) | 777 | v = self._remotes.get(name) |
| 763 | if not v: | 778 | if not v: |
| 764 | raise ManifestParseError, \ | 779 | raise ManifestParseError("remote %s not defined in %s" % |
| 765 | "remote %s not defined in %s" % \ | 780 | (name, self.manifestFile)) |
| 766 | (name, self.manifestFile) | ||
| 767 | return v | 781 | return v |
| 768 | 782 | ||
| 769 | def _reqatt(self, node, attname): | 783 | def _reqatt(self, node, attname): |
| @@ -772,7 +786,6 @@ class XmlManifest(object): | |||
| 772 | """ | 786 | """ |
| 773 | v = node.getAttribute(attname) | 787 | v = node.getAttribute(attname) |
| 774 | if not v: | 788 | if not v: |
| 775 | raise ManifestParseError, \ | 789 | raise ManifestParseError("no %s in <%s> within %s" % |
| 776 | "no %s in <%s> within %s" % \ | 790 | (attname, node.nodeName, self.manifestFile)) |
| 777 | (attname, node.nodeName, self.manifestFile) | ||
| 778 | return v | 791 | return v |
| @@ -36,6 +36,11 @@ from trace import IsTrace, Trace | |||
| 36 | 36 | ||
| 37 | from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M | 37 | from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M |
| 38 | 38 | ||
| 39 | try: | ||
| 40 | input = raw_input | ||
| 41 | except NameError: | ||
| 42 | pass | ||
| 43 | |||
| 39 | def _lwrite(path, content): | 44 | def _lwrite(path, content): |
| 40 | lock = '%s.lock' % path | 45 | lock = '%s.lock' % path |
| 41 | 46 | ||
| @@ -78,7 +83,7 @@ def _ProjectHooks(): | |||
| 78 | if _project_hook_list is None: | 83 | if _project_hook_list is None: |
| 79 | d = os.path.abspath(os.path.dirname(__file__)) | 84 | d = os.path.abspath(os.path.dirname(__file__)) |
| 80 | d = os.path.join(d , 'hooks') | 85 | d = os.path.join(d , 'hooks') |
| 81 | _project_hook_list = map(lambda x: os.path.join(d, x), os.listdir(d)) | 86 | _project_hook_list = [os.path.join(d, x) for x in os.listdir(d)] |
| 82 | return _project_hook_list | 87 | return _project_hook_list |
| 83 | 88 | ||
| 84 | 89 | ||
| @@ -361,7 +366,7 @@ class RepoHook(object): | |||
| 361 | 'Do you want to allow this script to run ' | 366 | 'Do you want to allow this script to run ' |
| 362 | '(yes/yes-never-ask-again/NO)? ') % ( | 367 | '(yes/yes-never-ask-again/NO)? ') % ( |
| 363 | self._GetMustVerb(), self._script_fullpath) | 368 | self._GetMustVerb(), self._script_fullpath) |
| 364 | response = raw_input(prompt).lower() | 369 | response = input(prompt).lower() |
| 365 | print() | 370 | print() |
| 366 | 371 | ||
| 367 | # User is doing a one-time approval. | 372 | # User is doing a one-time approval. |
| @@ -488,6 +493,7 @@ class Project(object): | |||
| 488 | groups = None, | 493 | groups = None, |
| 489 | sync_c = False, | 494 | sync_c = False, |
| 490 | sync_s = False, | 495 | sync_s = False, |
| 496 | clone_depth = None, | ||
| 491 | upstream = None, | 497 | upstream = None, |
| 492 | parent = None, | 498 | parent = None, |
| 493 | is_derived = False): | 499 | is_derived = False): |
| @@ -533,6 +539,7 @@ class Project(object): | |||
| 533 | self.groups = groups | 539 | self.groups = groups |
| 534 | self.sync_c = sync_c | 540 | self.sync_c = sync_c |
| 535 | self.sync_s = sync_s | 541 | self.sync_s = sync_s |
| 542 | self.clone_depth = clone_depth | ||
| 536 | self.upstream = upstream | 543 | self.upstream = upstream |
| 537 | self.parent = parent | 544 | self.parent = parent |
| 538 | self.is_derived = is_derived | 545 | self.is_derived = is_derived |
| @@ -644,7 +651,7 @@ class Project(object): | |||
| 644 | all_refs = self._allrefs | 651 | all_refs = self._allrefs |
| 645 | heads = {} | 652 | heads = {} |
| 646 | 653 | ||
| 647 | for name, ref_id in all_refs.iteritems(): | 654 | for name, ref_id in all_refs.items(): |
| 648 | if name.startswith(R_HEADS): | 655 | if name.startswith(R_HEADS): |
| 649 | name = name[len(R_HEADS):] | 656 | name = name[len(R_HEADS):] |
| 650 | b = self.GetBranch(name) | 657 | b = self.GetBranch(name) |
| @@ -653,7 +660,7 @@ class Project(object): | |||
| 653 | b.revision = ref_id | 660 | b.revision = ref_id |
| 654 | heads[name] = b | 661 | heads[name] = b |
| 655 | 662 | ||
| 656 | for name, ref_id in all_refs.iteritems(): | 663 | for name, ref_id in all_refs.items(): |
| 657 | if name.startswith(R_PUB): | 664 | if name.startswith(R_PUB): |
| 658 | name = name[len(R_PUB):] | 665 | name = name[len(R_PUB):] |
| 659 | b = heads.get(name) | 666 | b = heads.get(name) |
| @@ -672,9 +679,14 @@ class Project(object): | |||
| 672 | project_groups: "all,group1,group2" | 679 | project_groups: "all,group1,group2" |
| 673 | manifest_groups: "-group1,group2" | 680 | manifest_groups: "-group1,group2" |
| 674 | the project will be matched. | 681 | the project will be matched. |
| 682 | |||
| 683 | The special manifest group "default" will match any project that | ||
| 684 | does not have the special project group "notdefault" | ||
| 675 | """ | 685 | """ |
| 676 | expanded_manifest_groups = manifest_groups or ['all', '-notdefault'] | 686 | expanded_manifest_groups = manifest_groups or ['default'] |
| 677 | expanded_project_groups = ['all'] + (self.groups or []) | 687 | expanded_project_groups = ['all'] + (self.groups or []) |
| 688 | if not 'notdefault' in expanded_project_groups: | ||
| 689 | expanded_project_groups += ['default'] | ||
| 678 | 690 | ||
| 679 | matched = False | 691 | matched = False |
| 680 | for group in expanded_manifest_groups: | 692 | for group in expanded_manifest_groups: |
| @@ -754,10 +766,7 @@ class Project(object): | |||
| 754 | paths.extend(df.keys()) | 766 | paths.extend(df.keys()) |
| 755 | paths.extend(do) | 767 | paths.extend(do) |
| 756 | 768 | ||
| 757 | paths = list(set(paths)) | 769 | for p in sorted(set(paths)): |
| 758 | paths.sort() | ||
| 759 | |||
| 760 | for p in paths: | ||
| 761 | try: | 770 | try: |
| 762 | i = di[p] | 771 | i = di[p] |
| 763 | except KeyError: | 772 | except KeyError: |
| @@ -849,13 +858,13 @@ class Project(object): | |||
| 849 | all_refs = self._allrefs | 858 | all_refs = self._allrefs |
| 850 | heads = set() | 859 | heads = set() |
| 851 | canrm = {} | 860 | canrm = {} |
| 852 | for name, ref_id in all_refs.iteritems(): | 861 | for name, ref_id in all_refs.items(): |
| 853 | if name.startswith(R_HEADS): | 862 | if name.startswith(R_HEADS): |
| 854 | heads.add(name) | 863 | heads.add(name) |
| 855 | elif name.startswith(R_PUB): | 864 | elif name.startswith(R_PUB): |
| 856 | canrm[name] = ref_id | 865 | canrm[name] = ref_id |
| 857 | 866 | ||
| 858 | for name, ref_id in canrm.iteritems(): | 867 | for name, ref_id in canrm.items(): |
| 859 | n = name[len(R_PUB):] | 868 | n = name[len(R_PUB):] |
| 860 | if R_HEADS + n not in heads: | 869 | if R_HEADS + n not in heads: |
| 861 | self.bare_git.DeleteRef(name, ref_id) | 870 | self.bare_git.DeleteRef(name, ref_id) |
| @@ -866,14 +875,14 @@ class Project(object): | |||
| 866 | heads = {} | 875 | heads = {} |
| 867 | pubed = {} | 876 | pubed = {} |
| 868 | 877 | ||
| 869 | for name, ref_id in self._allrefs.iteritems(): | 878 | for name, ref_id in self._allrefs.items(): |
| 870 | if name.startswith(R_HEADS): | 879 | if name.startswith(R_HEADS): |
| 871 | heads[name[len(R_HEADS):]] = ref_id | 880 | heads[name[len(R_HEADS):]] = ref_id |
| 872 | elif name.startswith(R_PUB): | 881 | elif name.startswith(R_PUB): |
| 873 | pubed[name[len(R_PUB):]] = ref_id | 882 | pubed[name[len(R_PUB):]] = ref_id |
| 874 | 883 | ||
| 875 | ready = [] | 884 | ready = [] |
| 876 | for branch, ref_id in heads.iteritems(): | 885 | for branch, ref_id in heads.items(): |
| 877 | if branch in pubed and pubed[branch] == ref_id: | 886 | if branch in pubed and pubed[branch] == ref_id: |
| 878 | continue | 887 | continue |
| 879 | if selected_branch and branch != selected_branch: | 888 | if selected_branch and branch != selected_branch: |
| @@ -1218,7 +1227,7 @@ class Project(object): | |||
| 1218 | cmd = ['fetch', remote.name] | 1227 | cmd = ['fetch', remote.name] |
| 1219 | cmd.append('refs/changes/%2.2d/%d/%d' \ | 1228 | cmd.append('refs/changes/%2.2d/%d/%d' \ |
| 1220 | % (change_id % 100, change_id, patch_id)) | 1229 | % (change_id % 100, change_id, patch_id)) |
| 1221 | cmd.extend(map(str, remote.fetch)) | 1230 | cmd.extend(list(map(str, remote.fetch))) |
| 1222 | if GitCommand(self, cmd, bare=True).Wait() != 0: | 1231 | if GitCommand(self, cmd, bare=True).Wait() != 0: |
| 1223 | return None | 1232 | return None |
| 1224 | return DownloadedChange(self, | 1233 | return DownloadedChange(self, |
| @@ -1607,7 +1616,7 @@ class Project(object): | |||
| 1607 | ids = set(all_refs.values()) | 1616 | ids = set(all_refs.values()) |
| 1608 | tmp = set() | 1617 | tmp = set() |
| 1609 | 1618 | ||
| 1610 | for r, ref_id in GitRefs(ref_dir).all.iteritems(): | 1619 | for r, ref_id in GitRefs(ref_dir).all.items(): |
| 1611 | if r not in all_refs: | 1620 | if r not in all_refs: |
| 1612 | if r.startswith(R_TAGS) or remote.WritesTo(r): | 1621 | if r.startswith(R_TAGS) or remote.WritesTo(r): |
| 1613 | all_refs[r] = ref_id | 1622 | all_refs[r] = ref_id |
| @@ -1622,13 +1631,10 @@ class Project(object): | |||
| 1622 | ids.add(ref_id) | 1631 | ids.add(ref_id) |
| 1623 | tmp.add(r) | 1632 | tmp.add(r) |
| 1624 | 1633 | ||
| 1625 | ref_names = list(all_refs.keys()) | ||
| 1626 | ref_names.sort() | ||
| 1627 | |||
| 1628 | tmp_packed = '' | 1634 | tmp_packed = '' |
| 1629 | old_packed = '' | 1635 | old_packed = '' |
| 1630 | 1636 | ||
| 1631 | for r in ref_names: | 1637 | for r in sorted(all_refs): |
| 1632 | line = '%s %s\n' % (all_refs[r], r) | 1638 | line = '%s %s\n' % (all_refs[r], r) |
| 1633 | tmp_packed += line | 1639 | tmp_packed += line |
| 1634 | if r not in tmp: | 1640 | if r not in tmp: |
| @@ -1642,7 +1648,10 @@ class Project(object): | |||
| 1642 | 1648 | ||
| 1643 | # The --depth option only affects the initial fetch; after that we'll do | 1649 | # The --depth option only affects the initial fetch; after that we'll do |
| 1644 | # full fetches of changes. | 1650 | # full fetches of changes. |
| 1645 | depth = self.manifest.manifestProject.config.GetString('repo.depth') | 1651 | if self.clone_depth: |
| 1652 | depth = self.clone_depth | ||
| 1653 | else: | ||
| 1654 | depth = self.manifest.manifestProject.config.GetString('repo.depth') | ||
| 1646 | if depth and initial: | 1655 | if depth and initial: |
| 1647 | cmd.append('--depth=%s' % depth) | 1656 | cmd.append('--depth=%s' % depth) |
| 1648 | 1657 | ||
| @@ -1654,11 +1663,13 @@ class Project(object): | |||
| 1654 | 1663 | ||
| 1655 | if not current_branch_only: | 1664 | if not current_branch_only: |
| 1656 | # Fetch whole repo | 1665 | # Fetch whole repo |
| 1657 | if no_tags: | 1666 | # If using depth then we should not get all the tags since they may |
| 1667 | # be outside of the depth. | ||
| 1668 | if no_tags or depth: | ||
| 1658 | cmd.append('--no-tags') | 1669 | cmd.append('--no-tags') |
| 1659 | else: | 1670 | else: |
| 1660 | cmd.append('--tags') | 1671 | cmd.append('--tags') |
| 1661 | cmd.append((u'+refs/heads/*:') + remote.ToLocal('refs/heads/*')) | 1672 | cmd.append(str((u'+refs/heads/*:') + remote.ToLocal('refs/heads/*'))) |
| 1662 | elif tag_name is not None: | 1673 | elif tag_name is not None: |
| 1663 | cmd.append('tag') | 1674 | cmd.append('tag') |
| 1664 | cmd.append(tag_name) | 1675 | cmd.append(tag_name) |
| @@ -1668,7 +1679,7 @@ class Project(object): | |||
| 1668 | branch = self.upstream | 1679 | branch = self.upstream |
| 1669 | if branch.startswith(R_HEADS): | 1680 | if branch.startswith(R_HEADS): |
| 1670 | branch = branch[len(R_HEADS):] | 1681 | branch = branch[len(R_HEADS):] |
| 1671 | cmd.append((u'+refs/heads/%s:' % branch) + remote.ToLocal('refs/heads/%s' % branch)) | 1682 | cmd.append(str((u'+refs/heads/%s:' % branch) + remote.ToLocal('refs/heads/%s' % branch))) |
| 1672 | 1683 | ||
| 1673 | ok = False | 1684 | ok = False |
| 1674 | for _i in range(2): | 1685 | for _i in range(2): |
| @@ -1702,7 +1713,7 @@ class Project(object): | |||
| 1702 | return ok | 1713 | return ok |
| 1703 | 1714 | ||
| 1704 | def _ApplyCloneBundle(self, initial=False, quiet=False): | 1715 | def _ApplyCloneBundle(self, initial=False, quiet=False): |
| 1705 | if initial and self.manifest.manifestProject.config.GetString('repo.depth'): | 1716 | if initial and (self.manifest.manifestProject.config.GetString('repo.depth') or self.clone_depth): |
| 1706 | return False | 1717 | return False |
| 1707 | 1718 | ||
| 1708 | remote = self.GetRemote(self.remote.name) | 1719 | remote = self.GetRemote(self.remote.name) |
| @@ -2099,6 +2110,10 @@ class Project(object): | |||
| 2099 | line = fd.read() | 2110 | line = fd.read() |
| 2100 | finally: | 2111 | finally: |
| 2101 | fd.close() | 2112 | fd.close() |
| 2113 | try: | ||
| 2114 | line = line.decode() | ||
| 2115 | except AttributeError: | ||
| 2116 | pass | ||
| 2102 | if line.startswith('ref: '): | 2117 | if line.startswith('ref: '): |
| 2103 | return line[5:-1] | 2118 | return line[5:-1] |
| 2104 | return line[:-1] | 2119 | return line[:-1] |
| @@ -2192,7 +2207,7 @@ class Project(object): | |||
| 2192 | if not git_require((1, 7, 2)): | 2207 | if not git_require((1, 7, 2)): |
| 2193 | raise ValueError('cannot set config on command line for %s()' | 2208 | raise ValueError('cannot set config on command line for %s()' |
| 2194 | % name) | 2209 | % name) |
| 2195 | for k, v in config.iteritems(): | 2210 | for k, v in config.items(): |
| 2196 | cmdv.append('-c') | 2211 | cmdv.append('-c') |
| 2197 | cmdv.append('%s=%s' % (k, v)) | 2212 | cmdv.append('%s=%s' % (k, v)) |
| 2198 | cmdv.append(name) | 2213 | cmdv.append(name) |
| @@ -2208,6 +2223,10 @@ class Project(object): | |||
| 2208 | name, | 2223 | name, |
| 2209 | p.stderr)) | 2224 | p.stderr)) |
| 2210 | r = p.stdout | 2225 | r = p.stdout |
| 2226 | try: | ||
| 2227 | r = r.decode() | ||
| 2228 | except AttributeError: | ||
| 2229 | pass | ||
| 2211 | if r.endswith('\n') and r.index('\n') == len(r) - 1: | 2230 | if r.endswith('\n') and r.index('\n') == len(r) - 1: |
| 2212 | return r[:-1] | 2231 | return r[:-1] |
| 2213 | return r | 2232 | return r |
| @@ -108,6 +108,7 @@ repodir = '.repo' # name of repo's private directory | |||
| 108 | S_repo = 'repo' # special repo repository | 108 | S_repo = 'repo' # special repo repository |
| 109 | S_manifests = 'manifests' # special manifest repository | 109 | S_manifests = 'manifests' # special manifest repository |
| 110 | REPO_MAIN = S_repo + '/main.py' # main script | 110 | REPO_MAIN = S_repo + '/main.py' # main script |
| 111 | MIN_PYTHON_VERSION = (2, 6) # minimum supported python version | ||
| 111 | 112 | ||
| 112 | 113 | ||
| 113 | import optparse | 114 | import optparse |
| @@ -129,6 +130,19 @@ else: | |||
| 129 | urllib.request = urllib2 | 130 | urllib.request = urllib2 |
| 130 | urllib.error = urllib2 | 131 | urllib.error = urllib2 |
| 131 | 132 | ||
| 133 | # Python version check | ||
| 134 | ver = sys.version_info | ||
| 135 | if ver[0] == 3: | ||
| 136 | print('error: Python 3 support is not fully implemented in repo yet.\n' | ||
| 137 | 'Please use Python 2.6 - 2.7 instead.', | ||
| 138 | file=sys.stderr) | ||
| 139 | sys.exit(1) | ||
| 140 | if (ver[0], ver[1]) < MIN_PYTHON_VERSION: | ||
| 141 | print('error: Python version %s unsupported.\n' | ||
| 142 | 'Please use Python 2.6 - 2.7 instead.' | ||
| 143 | % sys.version.split(' ')[0], file=sys.stderr) | ||
| 144 | sys.exit(1) | ||
| 145 | |||
| 132 | home_dot_repo = os.path.expanduser('~/.repoconfig') | 146 | home_dot_repo = os.path.expanduser('~/.repoconfig') |
| 133 | gpg_dir = os.path.join(home_dot_repo, 'gnupg') | 147 | gpg_dir = os.path.join(home_dot_repo, 'gnupg') |
| 134 | 148 | ||
| @@ -164,7 +178,8 @@ group.add_option('--depth', type='int', default=None, | |||
| 164 | help='create a shallow clone with given depth; see git clone') | 178 | help='create a shallow clone with given depth; see git clone') |
| 165 | group.add_option('-g', '--groups', | 179 | group.add_option('-g', '--groups', |
| 166 | dest='groups', default='default', | 180 | dest='groups', default='default', |
| 167 | help='restrict manifest projects to ones with a specified group', | 181 | help='restrict manifest projects to ones with specified ' |
| 182 | 'group(s) [default|all|G1,G2,G3|G4,-G5,-G6]', | ||
| 168 | metavar='GROUP') | 183 | metavar='GROUP') |
| 169 | group.add_option('-p', '--platform', | 184 | group.add_option('-p', '--platform', |
| 170 | dest='platform', default="auto", | 185 | dest='platform', default="auto", |
diff --git a/subcmds/__init__.py b/subcmds/__init__.py index 1fac802e..84efb4de 100644 --- a/subcmds/__init__.py +++ b/subcmds/__init__.py | |||
| @@ -38,8 +38,8 @@ for py in os.listdir(my_dir): | |||
| 38 | try: | 38 | try: |
| 39 | cmd = getattr(mod, clsn)() | 39 | cmd = getattr(mod, clsn)() |
| 40 | except AttributeError: | 40 | except AttributeError: |
| 41 | raise SyntaxError, '%s/%s does not define class %s' % ( | 41 | raise SyntaxError('%s/%s does not define class %s' % ( |
| 42 | __name__, py, clsn) | 42 | __name__, py, clsn)) |
| 43 | 43 | ||
| 44 | name = name.replace('_', '-') | 44 | name = name.replace('_', '-') |
| 45 | cmd.NAME = name | 45 | cmd.NAME = name |
diff --git a/subcmds/branches.py b/subcmds/branches.py index 06d45abe..c2e7c4b9 100644 --- a/subcmds/branches.py +++ b/subcmds/branches.py | |||
| @@ -98,14 +98,13 @@ is shown, then the branch appears in all projects. | |||
| 98 | project_cnt = len(projects) | 98 | project_cnt = len(projects) |
| 99 | 99 | ||
| 100 | for project in projects: | 100 | for project in projects: |
| 101 | for name, b in project.GetBranches().iteritems(): | 101 | for name, b in project.GetBranches().items(): |
| 102 | b.project = project | 102 | b.project = project |
| 103 | if name not in all_branches: | 103 | if name not in all_branches: |
| 104 | all_branches[name] = BranchInfo(name) | 104 | all_branches[name] = BranchInfo(name) |
| 105 | all_branches[name].add(b) | 105 | all_branches[name].add(b) |
| 106 | 106 | ||
| 107 | names = all_branches.keys() | 107 | names = list(sorted(all_branches)) |
| 108 | names.sort() | ||
| 109 | 108 | ||
| 110 | if not names: | 109 | if not names: |
| 111 | print(' (no branches)', file=sys.stderr) | 110 | print(' (no branches)', file=sys.stderr) |
diff --git a/subcmds/forall.py b/subcmds/forall.py index 4c1c9ff8..7d5f7794 100644 --- a/subcmds/forall.py +++ b/subcmds/forall.py | |||
| @@ -42,10 +42,14 @@ class Forall(Command, MirrorSafeCommand): | |||
| 42 | helpSummary = "Run a shell command in each project" | 42 | helpSummary = "Run a shell command in each project" |
| 43 | helpUsage = """ | 43 | helpUsage = """ |
| 44 | %prog [<project>...] -c <command> [<arg>...] | 44 | %prog [<project>...] -c <command> [<arg>...] |
| 45 | %prog -r str1 [str2] ... -c <command> [<arg>...]" | ||
| 45 | """ | 46 | """ |
| 46 | helpDescription = """ | 47 | helpDescription = """ |
| 47 | Executes the same shell command in each project. | 48 | Executes the same shell command in each project. |
| 48 | 49 | ||
| 50 | The -r option allows running the command only on projects matching | ||
| 51 | regex or wildcard expression. | ||
| 52 | |||
| 49 | Output Formatting | 53 | Output Formatting |
| 50 | ----------------- | 54 | ----------------- |
| 51 | 55 | ||
| @@ -103,6 +107,9 @@ without iterating through the remaining projects. | |||
| 103 | setattr(parser.values, option.dest, list(parser.rargs)) | 107 | setattr(parser.values, option.dest, list(parser.rargs)) |
| 104 | while parser.rargs: | 108 | while parser.rargs: |
| 105 | del parser.rargs[0] | 109 | del parser.rargs[0] |
| 110 | p.add_option('-r', '--regex', | ||
| 111 | dest='regex', action='store_true', | ||
| 112 | help="Execute the command only on projects matching regex or wildcard expression") | ||
| 106 | p.add_option('-c', '--command', | 113 | p.add_option('-c', '--command', |
| 107 | help='Command (and arguments) to execute', | 114 | help='Command (and arguments) to execute', |
| 108 | dest='command', | 115 | dest='command', |
| @@ -166,7 +173,12 @@ without iterating through the remaining projects. | |||
| 166 | rc = 0 | 173 | rc = 0 |
| 167 | first = True | 174 | first = True |
| 168 | 175 | ||
| 169 | for project in self.GetProjects(args): | 176 | if not opt.regex: |
| 177 | projects = self.GetProjects(args) | ||
| 178 | else: | ||
| 179 | projects = self.FindProjects(args) | ||
| 180 | |||
| 181 | for project in projects: | ||
| 170 | env = os.environ.copy() | 182 | env = os.environ.copy() |
| 171 | def setenv(name, val): | 183 | def setenv(name, val): |
| 172 | if val is None: | 184 | if val is None: |
diff --git a/subcmds/help.py b/subcmds/help.py index 78428825..4aa3f863 100644 --- a/subcmds/help.py +++ b/subcmds/help.py | |||
| @@ -34,8 +34,7 @@ Displays detailed usage information about a command. | |||
| 34 | def _PrintAllCommands(self): | 34 | def _PrintAllCommands(self): |
| 35 | print('usage: repo COMMAND [ARGS]') | 35 | print('usage: repo COMMAND [ARGS]') |
| 36 | print('The complete list of recognized repo commands are:') | 36 | print('The complete list of recognized repo commands are:') |
| 37 | commandNames = self.commands.keys() | 37 | commandNames = list(sorted(self.commands)) |
| 38 | commandNames.sort() | ||
| 39 | 38 | ||
| 40 | maxlen = 0 | 39 | maxlen = 0 |
| 41 | for name in commandNames: | 40 | for name in commandNames: |
| @@ -55,10 +54,9 @@ Displays detailed usage information about a command. | |||
| 55 | def _PrintCommonCommands(self): | 54 | def _PrintCommonCommands(self): |
| 56 | print('usage: repo COMMAND [ARGS]') | 55 | print('usage: repo COMMAND [ARGS]') |
| 57 | print('The most commonly used repo commands are:') | 56 | print('The most commonly used repo commands are:') |
| 58 | commandNames = [name | 57 | commandNames = list(sorted([name |
| 59 | for name in self.commands.keys() | 58 | for name, command in self.commands.items() |
| 60 | if self.commands[name].common] | 59 | if command.common])) |
| 61 | commandNames.sort() | ||
| 62 | 60 | ||
| 63 | maxlen = 0 | 61 | maxlen = 0 |
| 64 | for name in commandNames: | 62 | for name in commandNames: |
diff --git a/subcmds/info.py b/subcmds/info.py index 325874b5..c10e56cd 100644 --- a/subcmds/info.py +++ b/subcmds/info.py | |||
| @@ -163,7 +163,7 @@ class Info(PagedCommand): | |||
| 163 | all_branches = [] | 163 | all_branches = [] |
| 164 | for project in self.GetProjects(args): | 164 | for project in self.GetProjects(args): |
| 165 | br = [project.GetUploadableBranch(x) | 165 | br = [project.GetUploadableBranch(x) |
| 166 | for x in project.GetBranches().keys()] | 166 | for x in project.GetBranches()] |
| 167 | br = [x for x in br if x] | 167 | br = [x for x in br if x] |
| 168 | if self.opt.current_branch: | 168 | if self.opt.current_branch: |
| 169 | br = [x for x in br if x.name == project.CurrentBranch] | 169 | br = [x for x in br if x.name == project.CurrentBranch] |
diff --git a/subcmds/init.py b/subcmds/init.py index 11312601..29730cc4 100644 --- a/subcmds/init.py +++ b/subcmds/init.py | |||
| @@ -91,8 +91,9 @@ to update the working directory files. | |||
| 91 | dest='depth', | 91 | dest='depth', |
| 92 | help='create a shallow clone with given depth; see git clone') | 92 | help='create a shallow clone with given depth; see git clone') |
| 93 | g.add_option('-g', '--groups', | 93 | g.add_option('-g', '--groups', |
| 94 | dest='groups', default='all,-notdefault', | 94 | dest='groups', default='default', |
| 95 | help='restrict manifest projects to ones with a specified group', | 95 | help='restrict manifest projects to ones with specified ' |
| 96 | 'group(s) [default|all|G1,G2,G3|G4,-G5,-G6]', | ||
| 96 | metavar='GROUP') | 97 | metavar='GROUP') |
| 97 | g.add_option('-p', '--platform', | 98 | g.add_option('-p', '--platform', |
| 98 | dest='platform', default='auto', | 99 | dest='platform', default='auto', |
| @@ -169,7 +170,7 @@ to update the working directory files. | |||
| 169 | 170 | ||
| 170 | groups = [x for x in groups if x] | 171 | groups = [x for x in groups if x] |
| 171 | groupstr = ','.join(groups) | 172 | groupstr = ','.join(groups) |
| 172 | if opt.platform == 'auto' and groupstr == 'all,-notdefault,platform-' + platform.system().lower(): | 173 | if opt.platform == 'auto' and groupstr == 'default,platform-' + platform.system().lower(): |
| 173 | groupstr = None | 174 | groupstr = None |
| 174 | m.config.SetString('manifest.groups', groupstr) | 175 | m.config.SetString('manifest.groups', groupstr) |
| 175 | 176 | ||
diff --git a/subcmds/list.py b/subcmds/list.py index 0d5c27f7..a3358245 100644 --- a/subcmds/list.py +++ b/subcmds/list.py | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | # limitations under the License. | 14 | # limitations under the License. |
| 15 | 15 | ||
| 16 | from __future__ import print_function | 16 | from __future__ import print_function |
| 17 | import re | 17 | import sys |
| 18 | 18 | ||
| 19 | from command import Command, MirrorSafeCommand | 19 | from command import Command, MirrorSafeCommand |
| 20 | 20 | ||
| @@ -38,6 +38,12 @@ This is similar to running: repo forall -c 'echo "$REPO_PATH : $REPO_PROJECT"'. | |||
| 38 | p.add_option('-f', '--fullpath', | 38 | p.add_option('-f', '--fullpath', |
| 39 | dest='fullpath', action='store_true', | 39 | dest='fullpath', action='store_true', |
| 40 | help="Display the full work tree path instead of the relative path") | 40 | help="Display the full work tree path instead of the relative path") |
| 41 | p.add_option('-n', '--name-only', | ||
| 42 | dest='name_only', action='store_true', | ||
| 43 | help="Display only the name of the repository") | ||
| 44 | p.add_option('-p', '--path-only', | ||
| 45 | dest='path_only', action='store_true', | ||
| 46 | help="Display only the path of the repository") | ||
| 41 | 47 | ||
| 42 | def Execute(self, opt, args): | 48 | def Execute(self, opt, args): |
| 43 | """List all projects and the associated directories. | 49 | """List all projects and the associated directories. |
| @@ -50,6 +56,11 @@ This is similar to running: repo forall -c 'echo "$REPO_PATH : $REPO_PROJECT"'. | |||
| 50 | opt: The options. | 56 | opt: The options. |
| 51 | args: Positional args. Can be a list of projects to list, or empty. | 57 | args: Positional args. Can be a list of projects to list, or empty. |
| 52 | """ | 58 | """ |
| 59 | |||
| 60 | if opt.fullpath and opt.name_only: | ||
| 61 | print('error: cannot combine -f and -n', file=sys.stderr) | ||
| 62 | sys.exit(1) | ||
| 63 | |||
| 53 | if not opt.regex: | 64 | if not opt.regex: |
| 54 | projects = self.GetProjects(args) | 65 | projects = self.GetProjects(args) |
| 55 | else: | 66 | else: |
| @@ -62,18 +73,12 @@ This is similar to running: repo forall -c 'echo "$REPO_PATH : $REPO_PROJECT"'. | |||
| 62 | 73 | ||
| 63 | lines = [] | 74 | lines = [] |
| 64 | for project in projects: | 75 | for project in projects: |
| 65 | lines.append("%s : %s" % (_getpath(project), project.name)) | 76 | if opt.name_only and not opt.path_only: |
| 77 | lines.append("%s" % ( project.name)) | ||
| 78 | elif opt.path_only and not opt.name_only: | ||
| 79 | lines.append("%s" % (_getpath(project))) | ||
| 80 | else: | ||
| 81 | lines.append("%s : %s" % (_getpath(project), project.name)) | ||
| 66 | 82 | ||
| 67 | lines.sort() | 83 | lines.sort() |
| 68 | print('\n'.join(lines)) | 84 | print('\n'.join(lines)) |
| 69 | |||
| 70 | def FindProjects(self, args): | ||
| 71 | result = [] | ||
| 72 | for project in self.GetProjects(''): | ||
| 73 | for arg in args: | ||
| 74 | pattern = re.compile(r'%s' % arg, re.IGNORECASE) | ||
| 75 | if pattern.search(project.name) or pattern.search(project.relpath): | ||
| 76 | result.append(project) | ||
| 77 | break | ||
| 78 | result.sort(key=lambda project: project.relpath) | ||
| 79 | return result | ||
diff --git a/subcmds/overview.py b/subcmds/overview.py index 418459ae..eed8cf20 100644 --- a/subcmds/overview.py +++ b/subcmds/overview.py | |||
| @@ -42,7 +42,7 @@ are displayed. | |||
| 42 | all_branches = [] | 42 | all_branches = [] |
| 43 | for project in self.GetProjects(args): | 43 | for project in self.GetProjects(args): |
| 44 | br = [project.GetUploadableBranch(x) | 44 | br = [project.GetUploadableBranch(x) |
| 45 | for x in project.GetBranches().keys()] | 45 | for x in project.GetBranches()] |
| 46 | br = [x for x in br if x] | 46 | br = [x for x in br if x] |
| 47 | if opt.current_branch: | 47 | if opt.current_branch: |
| 48 | br = [x for x in br if x.name == project.CurrentBranch] | 48 | br = [x for x in br if x.name == project.CurrentBranch] |
diff --git a/subcmds/stage.py b/subcmds/stage.py index ff15ee0c..28849764 100644 --- a/subcmds/stage.py +++ b/subcmds/stage.py | |||
| @@ -49,7 +49,7 @@ The '%prog' command stages files to prepare the next commit. | |||
| 49 | self.Usage() | 49 | self.Usage() |
| 50 | 50 | ||
| 51 | def _Interactive(self, opt, args): | 51 | def _Interactive(self, opt, args): |
| 52 | all_projects = filter(lambda x: x.IsDirty(), self.GetProjects(args)) | 52 | all_projects = [p for p in self.GetProjects(args) if p.IsDirty()] |
| 53 | if not all_projects: | 53 | if not all_projects: |
| 54 | print('no projects have uncommitted modifications', file=sys.stderr) | 54 | print('no projects have uncommitted modifications', file=sys.stderr) |
| 55 | return | 55 | return |
| @@ -98,9 +98,9 @@ The '%prog' command stages files to prepare the next commit. | |||
| 98 | _AddI(all_projects[a_index - 1]) | 98 | _AddI(all_projects[a_index - 1]) |
| 99 | continue | 99 | continue |
| 100 | 100 | ||
| 101 | p = filter(lambda x: x.name == a or x.relpath == a, all_projects) | 101 | projects = [p for p in all_projects if a in [p.name, p.relpath]] |
| 102 | if len(p) == 1: | 102 | if len(projects) == 1: |
| 103 | _AddI(p[0]) | 103 | _AddI(projects[0]) |
| 104 | continue | 104 | continue |
| 105 | print('Bye.') | 105 | print('Bye.') |
| 106 | 106 | ||
diff --git a/subcmds/status.py b/subcmds/status.py index cce00c81..9810337f 100644 --- a/subcmds/status.py +++ b/subcmds/status.py | |||
| @@ -21,10 +21,15 @@ except ImportError: | |||
| 21 | import dummy_threading as _threading | 21 | import dummy_threading as _threading |
| 22 | 22 | ||
| 23 | import glob | 23 | import glob |
| 24 | try: | ||
| 25 | # For python2 | ||
| 26 | import StringIO as io | ||
| 27 | except ImportError: | ||
| 28 | # For python3 | ||
| 29 | import io | ||
| 24 | import itertools | 30 | import itertools |
| 25 | import os | 31 | import os |
| 26 | import sys | 32 | import sys |
| 27 | import StringIO | ||
| 28 | 33 | ||
| 29 | from color import Coloring | 34 | from color import Coloring |
| 30 | 35 | ||
| @@ -142,7 +147,7 @@ the following meanings: | |||
| 142 | for project in all_projects: | 147 | for project in all_projects: |
| 143 | sem.acquire() | 148 | sem.acquire() |
| 144 | 149 | ||
| 145 | class BufList(StringIO.StringIO): | 150 | class BufList(io.StringIO): |
| 146 | def dump(self, ostream): | 151 | def dump(self, ostream): |
| 147 | for entry in self.buflist: | 152 | for entry in self.buflist: |
| 148 | ostream.write(entry) | 153 | ostream.write(entry) |
| @@ -182,7 +187,7 @@ the following meanings: | |||
| 182 | try: | 187 | try: |
| 183 | os.chdir(self.manifest.topdir) | 188 | os.chdir(self.manifest.topdir) |
| 184 | 189 | ||
| 185 | outstring = StringIO.StringIO() | 190 | outstring = io.StringIO() |
| 186 | self._FindOrphans(glob.glob('.*') + \ | 191 | self._FindOrphans(glob.glob('.*') + \ |
| 187 | glob.glob('*'), \ | 192 | glob.glob('*'), \ |
| 188 | proj_dirs, proj_dirs_parents, outstring) | 193 | proj_dirs, proj_dirs_parents, outstring) |
diff --git a/subcmds/sync.py b/subcmds/sync.py index 6c903ff4..8fb94885 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
| @@ -24,8 +24,24 @@ import socket | |||
| 24 | import subprocess | 24 | import subprocess |
| 25 | import sys | 25 | import sys |
| 26 | import time | 26 | import time |
| 27 | import urlparse | 27 | try: |
| 28 | import xmlrpclib | 28 | # For python3 |
| 29 | import urllib.parse | ||
| 30 | except ImportError: | ||
| 31 | # For python2 | ||
| 32 | import imp | ||
| 33 | import urlparse | ||
| 34 | urllib = imp.new_module('urllib') | ||
| 35 | urllib.parse = urlparse | ||
| 36 | try: | ||
| 37 | # For python3 | ||
| 38 | import xmlrpc.client | ||
| 39 | except ImportError: | ||
| 40 | # For python2 | ||
| 41 | import imp | ||
| 42 | import xmlrpclib | ||
| 43 | xmlrpc = imp.new_module('xmlrpc') | ||
| 44 | xmlrpc.client = xmlrpclib | ||
| 29 | 45 | ||
| 30 | try: | 46 | try: |
| 31 | import threading as _threading | 47 | import threading as _threading |
| @@ -228,6 +244,9 @@ later is required to fix a server side protocol bug. | |||
| 228 | # We'll set to true once we've locked the lock. | 244 | # We'll set to true once we've locked the lock. |
| 229 | did_lock = False | 245 | did_lock = False |
| 230 | 246 | ||
| 247 | if not opt.quiet: | ||
| 248 | print('Fetching project %s' % project.name) | ||
| 249 | |||
| 231 | # Encapsulate everything in a try/except/finally so that: | 250 | # Encapsulate everything in a try/except/finally so that: |
| 232 | # - We always set err_event in the case of an exception. | 251 | # - We always set err_event in the case of an exception. |
| 233 | # - We always make sure we call sem.release(). | 252 | # - We always make sure we call sem.release(). |
| @@ -274,6 +293,8 @@ later is required to fix a server side protocol bug. | |||
| 274 | if self.jobs == 1: | 293 | if self.jobs == 1: |
| 275 | for project in projects: | 294 | for project in projects: |
| 276 | pm.update() | 295 | pm.update() |
| 296 | if not opt.quiet: | ||
| 297 | print('Fetching project %s' % project.name) | ||
| 277 | if project.Sync_NetworkHalf( | 298 | if project.Sync_NetworkHalf( |
| 278 | quiet=opt.quiet, | 299 | quiet=opt.quiet, |
| 279 | current_branch_only=opt.current_branch_only, | 300 | current_branch_only=opt.current_branch_only, |
| @@ -372,6 +393,13 @@ later is required to fix a server side protocol bug. | |||
| 372 | print('\nerror: Exited sync due to gc errors', file=sys.stderr) | 393 | print('\nerror: Exited sync due to gc errors', file=sys.stderr) |
| 373 | sys.exit(1) | 394 | sys.exit(1) |
| 374 | 395 | ||
| 396 | def _ReloadManifest(self, manifest_name=None): | ||
| 397 | if manifest_name: | ||
| 398 | # Override calls _Unload already | ||
| 399 | self.manifest.Override(manifest_name) | ||
| 400 | else: | ||
| 401 | self.manifest._Unload() | ||
| 402 | |||
| 375 | def UpdateProjectList(self): | 403 | def UpdateProjectList(self): |
| 376 | new_project_paths = [] | 404 | new_project_paths = [] |
| 377 | for project in self.GetProjects(None, missing_ok=True): | 405 | for project in self.GetProjects(None, missing_ok=True): |
| @@ -486,7 +514,7 @@ later is required to fix a server side protocol bug. | |||
| 486 | file=sys.stderr) | 514 | file=sys.stderr) |
| 487 | else: | 515 | else: |
| 488 | try: | 516 | try: |
| 489 | parse_result = urlparse.urlparse(manifest_server) | 517 | parse_result = urllib.parse(manifest_server) |
| 490 | if parse_result.hostname: | 518 | if parse_result.hostname: |
| 491 | username, _account, password = \ | 519 | username, _account, password = \ |
| 492 | info.authenticators(parse_result.hostname) | 520 | info.authenticators(parse_result.hostname) |
| @@ -504,7 +532,7 @@ later is required to fix a server side protocol bug. | |||
| 504 | 1) | 532 | 1) |
| 505 | 533 | ||
| 506 | try: | 534 | try: |
| 507 | server = xmlrpclib.Server(manifest_server) | 535 | server = xmlrpc.client.Server(manifest_server) |
| 508 | if opt.smart_sync: | 536 | if opt.smart_sync: |
| 509 | p = self.manifest.manifestProject | 537 | p = self.manifest.manifestProject |
| 510 | b = p.GetBranch(p.CurrentBranch) | 538 | b = p.GetBranch(p.CurrentBranch) |
| @@ -513,8 +541,7 @@ later is required to fix a server side protocol bug. | |||
| 513 | branch = branch[len(R_HEADS):] | 541 | branch = branch[len(R_HEADS):] |
| 514 | 542 | ||
| 515 | env = os.environ.copy() | 543 | env = os.environ.copy() |
| 516 | if (env.has_key('TARGET_PRODUCT') and | 544 | if 'TARGET_PRODUCT' in env and 'TARGET_BUILD_VARIANT' in env: |
| 517 | env.has_key('TARGET_BUILD_VARIANT')): | ||
| 518 | target = '%s-%s' % (env['TARGET_PRODUCT'], | 545 | target = '%s-%s' % (env['TARGET_PRODUCT'], |
| 519 | env['TARGET_BUILD_VARIANT']) | 546 | env['TARGET_BUILD_VARIANT']) |
| 520 | [success, manifest_str] = server.GetApprovedManifest(branch, target) | 547 | [success, manifest_str] = server.GetApprovedManifest(branch, target) |
| @@ -542,11 +569,11 @@ later is required to fix a server side protocol bug. | |||
| 542 | else: | 569 | else: |
| 543 | print('error: %s' % manifest_str, file=sys.stderr) | 570 | print('error: %s' % manifest_str, file=sys.stderr) |
| 544 | sys.exit(1) | 571 | sys.exit(1) |
| 545 | except (socket.error, IOError, xmlrpclib.Fault) as e: | 572 | except (socket.error, IOError, xmlrpc.client.Fault) as e: |
| 546 | print('error: cannot connect to manifest server %s:\n%s' | 573 | print('error: cannot connect to manifest server %s:\n%s' |
| 547 | % (self.manifest.manifest_server, e), file=sys.stderr) | 574 | % (self.manifest.manifest_server, e), file=sys.stderr) |
| 548 | sys.exit(1) | 575 | sys.exit(1) |
| 549 | except xmlrpclib.ProtocolError as e: | 576 | except xmlrpc.client.ProtocolError as e: |
| 550 | print('error: cannot connect to manifest server %s:\n%d %s' | 577 | print('error: cannot connect to manifest server %s:\n%d %s' |
| 551 | % (self.manifest.manifest_server, e.errcode, e.errmsg), | 578 | % (self.manifest.manifest_server, e.errcode, e.errmsg), |
| 552 | file=sys.stderr) | 579 | file=sys.stderr) |
| @@ -571,7 +598,7 @@ later is required to fix a server side protocol bug. | |||
| 571 | mp.Sync_LocalHalf(syncbuf) | 598 | mp.Sync_LocalHalf(syncbuf) |
| 572 | if not syncbuf.Finish(): | 599 | if not syncbuf.Finish(): |
| 573 | sys.exit(1) | 600 | sys.exit(1) |
| 574 | self.manifest._Unload() | 601 | self._ReloadManifest(opt.manifest_name) |
| 575 | if opt.jobs is None: | 602 | if opt.jobs is None: |
| 576 | self.jobs = self.manifest.default.sync_j | 603 | self.jobs = self.manifest.default.sync_j |
| 577 | all_projects = self.GetProjects(args, | 604 | all_projects = self.GetProjects(args, |
| @@ -596,7 +623,7 @@ later is required to fix a server side protocol bug. | |||
| 596 | # Iteratively fetch missing and/or nested unregistered submodules | 623 | # Iteratively fetch missing and/or nested unregistered submodules |
| 597 | previously_missing_set = set() | 624 | previously_missing_set = set() |
| 598 | while True: | 625 | while True: |
| 599 | self.manifest._Unload() | 626 | self._ReloadManifest(opt.manifest_name) |
| 600 | all_projects = self.GetProjects(args, | 627 | all_projects = self.GetProjects(args, |
| 601 | missing_ok=True, | 628 | missing_ok=True, |
| 602 | submodules_ok=opt.fetch_submodules) | 629 | submodules_ok=opt.fetch_submodules) |
diff --git a/subcmds/upload.py b/subcmds/upload.py index 48ee685c..a34938e5 100644 --- a/subcmds/upload.py +++ b/subcmds/upload.py | |||
| @@ -23,6 +23,11 @@ from editor import Editor | |||
| 23 | from error import HookError, UploadError | 23 | from error import HookError, UploadError |
| 24 | from project import RepoHook | 24 | from project import RepoHook |
| 25 | 25 | ||
| 26 | try: | ||
| 27 | input = raw_input | ||
| 28 | except NameError: | ||
| 29 | pass | ||
| 30 | |||
| 26 | UNUSUAL_COMMIT_THRESHOLD = 5 | 31 | UNUSUAL_COMMIT_THRESHOLD = 5 |
| 27 | 32 | ||
| 28 | def _ConfirmManyUploads(multiple_branches=False): | 33 | def _ConfirmManyUploads(multiple_branches=False): |
| @@ -33,7 +38,7 @@ def _ConfirmManyUploads(multiple_branches=False): | |||
| 33 | print('ATTENTION: You are uploading an unusually high number of commits.') | 38 | print('ATTENTION: You are uploading an unusually high number of commits.') |
| 34 | print('YOU PROBABLY DO NOT MEAN TO DO THIS. (Did you rebase across ' | 39 | print('YOU PROBABLY DO NOT MEAN TO DO THIS. (Did you rebase across ' |
| 35 | 'branches?)') | 40 | 'branches?)') |
| 36 | answer = raw_input("If you are sure you intend to do this, type 'yes': ").strip() | 41 | answer = input("If you are sure you intend to do this, type 'yes': ").strip() |
| 37 | return answer == "yes" | 42 | return answer == "yes" |
| 38 | 43 | ||
| 39 | def _die(fmt, *args): | 44 | def _die(fmt, *args): |
