Merge "Change usages of xrange() to range()"
diff --git a/docs/manifest-format.txt b/docs/manifest-format.txt
index f499868..9589352 100644
--- a/docs/manifest-format.txt
+++ b/docs/manifest-format.txt
@@ -224,15 +224,19 @@
 the manifest repositories root.
 
 
-Local Manifest
-==============
+Local Manifests
+===============
 
-Additional remotes and projects may be added through a local
-manifest, stored in `$TOP_DIR/.repo/local_manifest.xml`.
+Additional remotes and projects may be added through local manifest
+files stored in `$TOP_DIR/.repo/local_manifests/*.xml`.
 
 For example:
 
-  $ cat .repo/local_manifest.xml
+  $ ls .repo/local_manifests
+  local_manifest.xml
+  another_local_manifest.xml
+
+  $ cat .repo/local_manifests/local_manifest.xml
   <?xml version="1.0" encoding="UTF-8"?>
   <manifest>
     <project path="manifest"
@@ -241,6 +245,11 @@
              name="platform/manifest" />
   </manifest>
 
-Users may add projects to the local manifest prior to a `repo sync`
+Users may add projects to the local manifest(s) prior to a `repo sync`
 invocation, instructing repo to automatically download and manage
 these extra projects.
+
+Additional remotes and projects may also be added through a local
+manifest, stored in `$TOP_DIR/.repo/local_manifest.xml`. This method
+is deprecated in favor of using multiple manifest files as mentioned
+above.
diff --git a/git_command.py b/git_command.py
index 39f795f..e5e28f3 100644
--- a/git_command.py
+++ b/git_command.py
@@ -88,7 +88,7 @@
       ver_str = git.version()
       if ver_str.startswith('git version '):
         _git_version = tuple(
-          map(lambda x: int(x),
+          map(int,
             ver_str[len('git version '):].strip().split('-')[0].split('.')[0:3]
           ))
       else:
@@ -110,7 +110,7 @@
   if min_version <= git_version:
     return True
   if fail:
-    need = '.'.join(map(lambda x: str(x), min_version))
+    need = '.'.join(map(str, min_version))
     print >>sys.stderr, 'fatal: git %s or later required' % need
     sys.exit(1)
   return False
diff --git a/git_config.py b/git_config.py
index 645c97a..f60893e 100644
--- a/git_config.py
+++ b/git_config.py
@@ -537,7 +537,7 @@
     self.url = self._Get('url')
     self.review = self._Get('review')
     self.projectname = self._Get('projectname')
-    self.fetch = map(lambda x: RefSpec.FromString(x),
+    self.fetch = map(RefSpec.FromString,
                      self._Get('fetch', all_keys=True))
     self._review_url = None
 
@@ -657,7 +657,7 @@
     self._Set('url', self.url)
     self._Set('review', self.review)
     self._Set('projectname', self.projectname)
-    self._Set('fetch', map(lambda x: str(x), self.fetch))
+    self._Set('fetch', map(str, self.fetch))
 
   def _Set(self, key, value):
     key = 'remote.%s.%s' % (self.name, key)
diff --git a/main.py b/main.py
index 14a5761..0c87c38 100755
--- a/main.py
+++ b/main.py
@@ -195,12 +195,12 @@
     sys.exit(1)
 
   exp = _CurrentWrapperVersion()
-  ver = tuple(map(lambda x: int(x), ver.split('.')))
+  ver = tuple(map(int, ver.split('.')))
   if len(ver) == 1:
     ver = (0, ver[0])
 
+  exp_str = '.'.join(map(str, exp))
   if exp[0] > ver[0] or ver < (0, 4):
-    exp_str = '.'.join(map(lambda x: str(x), exp))
     print >>sys.stderr, """
 !!! A new repo command (%5s) is available.    !!!
 !!! You must upgrade before you can continue:   !!!
@@ -210,7 +210,6 @@
     sys.exit(1)
 
   if exp > ver:
-    exp_str = '.'.join(map(lambda x: str(x), exp))
     print >>sys.stderr, """
 ... A new repo command (%5s) is available.
 ... You should upgrade soon:
@@ -272,7 +271,7 @@
     _user_agent = 'git-repo/%s (%s) git/%s Python/%d.%d.%d' % (
       repo_version,
       os_name,
-      '.'.join(map(lambda d: str(d), git.version_tuple())),
+      '.'.join(map(str, git.version_tuple())),
       py_version[0], py_version[1], py_version[2])
   return _user_agent
 
diff --git a/manifest_xml.py b/manifest_xml.py
index cdee87a..d16f1a9 100644
--- a/manifest_xml.py
+++ b/manifest_xml.py
@@ -27,6 +27,7 @@
 
 MANIFEST_FILE_NAME = 'manifest.xml'
 LOCAL_MANIFEST_NAME = 'local_manifest.xml'
+LOCAL_MANIFESTS_DIR_NAME = 'local_manifests'
 
 urlparse.uses_relative.extend(['ssh', 'git'])
 urlparse.uses_netloc.extend(['ssh', 'git'])
@@ -299,8 +300,21 @@
 
       local = os.path.join(self.repodir, LOCAL_MANIFEST_NAME)
       if os.path.exists(local):
+        print >>sys.stderr, 'warning: %s is deprecated; put local manifests in %s instead' % \
+                            (LOCAL_MANIFEST_NAME, LOCAL_MANIFESTS_DIR_NAME)
         nodes.append(self._ParseManifestXml(local, self.repodir))
 
+      local_dir = os.path.abspath(os.path.join(self.repodir, LOCAL_MANIFESTS_DIR_NAME))
+      try:
+        for local_file in os.listdir(local_dir):
+          if local_file.endswith('.xml'):
+            try:
+              nodes.append(self._ParseManifestXml(local_file, self.repodir))
+            except ManifestParseError as e:
+              print >>sys.stderr, '%s' % str(e)
+      except OSError:
+        pass
+
       self._ParseManifest(nodes)
 
       if self.IsMirror:
@@ -310,7 +324,11 @@
       self._loaded = True
 
   def _ParseManifestXml(self, path, include_root):
-    root = xml.dom.minidom.parse(path)
+    try:
+      root = xml.dom.minidom.parse(path)
+    except (OSError, xml.parsers.expat.ExpatError) as e:
+      raise ManifestParseError("error parsing manifest %s: %s" % (path, e))
+
     if not root or not root.childNodes:
       raise ManifestParseError("no root node in %s" % (path,))
 
diff --git a/project.py b/project.py
index cdb4ecf..f72b1c8 100644
--- a/project.py
+++ b/project.py
@@ -1175,7 +1175,7 @@
     cmd = ['fetch', remote.name]
     cmd.append('refs/changes/%2.2d/%d/%d' \
                % (change_id % 100, change_id, patch_id))
-    cmd.extend(map(lambda x: str(x), remote.fetch))
+    cmd.extend(map(str, remote.fetch))
     if GitCommand(self, cmd, bare=True).Wait() != 0:
       return None
     return DownloadedChange(self,
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 15f69f7..d638911 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -173,6 +173,12 @@
     p.add_option('--no-clone-bundle',
                  dest='no_clone_bundle', action='store_true',
                  help='disable use of /clone.bundle on HTTP/HTTPS')
+    p.add_option('-u', '--manifest-server-username', action='store',
+                 dest='manifest_server_username',
+                 help='username to authenticate with the manifest server')
+    p.add_option('-p', '--manifest-server-password', action='store',
+                 dest='manifest_server_password',
+                 help='password to authenticate with the manifest server')
     if show_smart:
       p.add_option('-s', '--smart-sync',
                    dest='smart_sync', action='store_true',
@@ -180,12 +186,6 @@
       p.add_option('-t', '--smart-tag',
                    dest='smart_tag', action='store',
                    help='smart sync using manifest from a known tag')
-      p.add_option('-u', '--manifest-server-username', action='store',
-                   dest='manifest_server_username',
-                   help='username to authenticate with the manifest server')
-      p.add_option('-p', '--manifest-server-password', action='store',
-                   dest='manifest_server_password',
-                   help='password to authenticate with the manifest server')
 
     g = p.add_option_group('repo Version options')
     g.add_option('--no-repo-verify',