diff --git a/manifest_submodule.py b/manifest_submodule.py
new file mode 100644
index 0000000..92f187a
--- /dev/null
+++ b/manifest_submodule.py
@@ -0,0 +1,474 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+import os
+import shutil
+
+from error import GitError
+from error import ManifestParseError
+from git_command import GitCommand
+from git_config import GitConfig
+from git_config import IsId
+from manifest import Manifest
+from progress import Progress
+from project import RemoteSpec
+from project import Project
+from project import MetaProject
+from project import R_HEADS
+from project import HEAD
+from project import _lwrite
+
+import manifest_xml
+
+GITLINK = '160000'
+
+def _rmdir(dir, top):
+  while dir != top:
+    try:
+      os.rmdir(dir)
+    except OSError:
+      break
+    dir = os.path.dirname(dir)
+
+def _rmref(gitdir, ref):
+  os.remove(os.path.join(gitdir, ref))
+  log = os.path.join(gitdir, 'logs', ref)
+  if os.path.exists(log):
+    os.remove(log)
+    _rmdir(os.path.dirname(log), gitdir)
+
+def _has_gitmodules(d):
+  return os.path.exists(os.path.join(d, '.gitmodules'))
+
+class SubmoduleManifest(Manifest):
+  """manifest from .gitmodules file"""
+
+  @classmethod
+  def Is(cls, repodir):
+    return _has_gitmodules(os.path.dirname(repodir)) \
+        or _has_gitmodules(os.path.join(repodir, 'manifest')) \
+        or _has_gitmodules(os.path.join(repodir, 'manifests'))
+
+  @classmethod
+  def IsBare(cls, p):
+    try:
+      p.bare_git.cat_file('-e', '%s:.gitmodules' % p.GetRevisionId())
+    except GitError:
+      return False
+    return True
+
+  def __init__(self, repodir):
+    Manifest.__init__(self, repodir)
+
+    gitdir = os.path.join(repodir, 'manifest.git')
+    config = GitConfig.ForRepository(gitdir = gitdir)
+
+    if config.GetBoolean('repo.mirror'):
+      worktree = os.path.join(repodir, 'manifest')
+      relpath = None
+    else:
+      worktree = self.topdir
+      relpath  = '.'
+
+    self.manifestProject = MetaProject(self, '__manifest__',
+      gitdir   = gitdir,
+      worktree = worktree,
+      relpath  = relpath)
+    self._modules = GitConfig(os.path.join(worktree, '.gitmodules'),
+                              pickleFile = os.path.join(
+                                repodir, '.repopickle_gitmodules'
+                              ))
+    self._review = GitConfig(os.path.join(worktree, '.review'),
+                             pickleFile = os.path.join(
+                               repodir, '.repopickle_review'
+                             ))
+    self._Unload()
+
+  @property
+  def projects(self):
+    self._Load()
+    return self._projects
+
+  def InitBranch(self):
+    m = self.manifestProject
+    if m.CurrentBranch is None:
+      b = m.revisionExpr
+      if b.startswith(R_HEADS):
+        b = b[len(R_HEADS):]
+      return m.StartBranch(b)
+    return True
+
+  def SetMRefs(self, project):
+    if project.revisionId is None:
+      # Special project, e.g. the manifest or repo executable.
+      #
+      return
+
+    ref = 'refs/remotes/m'
+    cur = project.bare_ref.get(ref)
+    exp = project.revisionId
+    if cur != exp:
+      msg = 'manifest set to %s' % exp
+      project.bare_git.UpdateRef(ref, exp, message = msg, detach = True)
+
+    ref = 'refs/remotes/m-revision'
+    cur = project.bare_ref.symref(ref)
+    exp = project.revisionExpr
+    if exp is None:
+      if cur:
+        _rmref(project.gitdir, ref)
+    elif cur != exp:
+      remote = project.GetRemote(project.remote.name)
+      dst = remote.ToLocal(exp)
+      msg = 'manifest set to %s (%s)' % (exp, dst)
+      project.bare_git.symbolic_ref('-m', msg, ref, dst)
+
+  def Upgrade_Local(self, old):
+    if isinstance(old, manifest_xml.XmlManifest):
+      self.FromXml_Local_1(old, checkout=True)
+      self.FromXml_Local_2(old)
+    else:
+      raise ManifestParseError, 'cannot upgrade manifest'
+
+  def FromXml_Local_1(self, old, checkout):
+    os.rename(old.manifestProject.gitdir,
+              os.path.join(old.repodir, 'manifest.git'))
+
+    oldmp = old.manifestProject
+    oldBranch = oldmp.CurrentBranch
+    b = oldmp.GetBranch(oldBranch).merge
+    if not b:
+      raise ManifestParseError, 'cannot upgrade manifest'
+    if b.startswith(R_HEADS):
+      b = b[len(R_HEADS):]
+
+    newmp = self.manifestProject
+    self._CleanOldMRefs(newmp)
+    if oldBranch != b:
+      newmp.bare_git.branch('-m', oldBranch, b)
+      newmp.config.ClearCache()
+
+    old_remote = newmp.GetBranch(b).remote.name
+    act_remote = self._GuessRemoteName(old)
+    if old_remote != act_remote:
+      newmp.bare_git.remote('rename', old_remote, act_remote)
+      newmp.config.ClearCache()
+    newmp.remote.name = act_remote
+    print >>sys.stderr, "Assuming remote named '%s'" % act_remote
+
+    if checkout:
+      for p in old.projects.values():
+        for c in p.copyfiles:
+          if os.path.exists(c.abs_dest):
+            os.remove(c.abs_dest)
+      newmp._InitWorkTree()
+    else:
+      newmp._LinkWorkTree()
+
+    _lwrite(os.path.join(newmp.worktree,'.git',HEAD),
+            'ref: refs/heads/%s\n' % b)
+
+  def _GuessRemoteName(self, old):
+    used = {}
+    for p in old.projects.values():
+      n = p.remote.name
+      used[n] = used.get(n, 0) + 1
+
+    remote_name = 'origin'
+    remote_used = 0
+    for n in used.keys():
+      if remote_used < used[n]:
+        remote_used = used[n]
+        remote_name = n
+    return remote_name
+
+  def FromXml_Local_2(self, old):
+    shutil.rmtree(old.manifestProject.worktree)
+    os.remove(old._manifestFile)
+
+    my_remote = self._Remote().name
+    new_base = os.path.join(self.repodir, 'projects')
+    old_base = os.path.join(self.repodir, 'projects.old')
+    os.rename(new_base, old_base)
+    os.makedirs(new_base)
+
+    info = []
+    pm = Progress('Converting projects', len(self.projects))
+    for p in self.projects.values():
+      pm.update()
+
+      old_p = old.projects.get(p.name)
+      old_gitdir = os.path.join(old_base, '%s.git' % p.relpath)
+      if not os.path.isdir(old_gitdir):
+        continue
+
+      parent = os.path.dirname(p.gitdir)
+      if not os.path.isdir(parent):
+        os.makedirs(parent)
+      os.rename(old_gitdir, p.gitdir)
+      _rmdir(os.path.dirname(old_gitdir), self.repodir)
+
+      if not os.path.isdir(p.worktree):
+        os.makedirs(p.worktree)
+
+      if os.path.isdir(os.path.join(p.worktree, '.git')):
+        p._LinkWorkTree(relink=True)
+
+      self._CleanOldMRefs(p)
+      if old_p and old_p.remote.name != my_remote:
+        info.append("%s/: renamed remote '%s' to '%s'" \
+                    % (p.relpath, old_p.remote.name, my_remote))
+        p.bare_git.remote('rename', old_p.remote.name, my_remote)
+        p.config.ClearCache()
+
+      self.SetMRefs(p)
+    pm.end()
+    for i in info:
+      print >>sys.stderr, i
+
+  def _CleanOldMRefs(self, p):
+    all_refs = p._allrefs
+    for ref in all_refs.keys():
+      if ref.startswith(manifest_xml.R_M):
+        if p.bare_ref.symref(ref) != '':
+          _rmref(p.gitdir, ref)
+        else:
+          p.bare_git.DeleteRef(ref, all_refs[ref])
+
+  def FromXml_Definition(self, old):
+    """Convert another manifest representation to this one.
+    """
+    mp = self.manifestProject
+    gm = self._modules
+    gr = self._review
+
+    fd = open(os.path.join(mp.worktree, '.gitignore'), 'ab')
+    fd.write('/.repo\n')
+    fd.close()
+
+    sort_projects = list(old.projects.keys())
+    sort_projects.sort()
+
+    b = mp.GetBranch(mp.CurrentBranch).merge
+    if b.startswith(R_HEADS):
+      b = b[len(R_HEADS):]
+
+    info = []
+    pm = Progress('Converting manifest', len(sort_projects))
+    for p in sort_projects:
+      pm.update()
+      p = old.projects[p]
+
+      gm.SetString('submodule.%s.path' % p.name, p.relpath)
+      gm.SetString('submodule.%s.url' % p.name, p.remote.url)
+
+      if gr.GetString('review.url') is None:
+        gr.SetString('review.url', p.remote.review)
+      elif gr.GetString('review.url') != p.remote.review:
+        gr.SetString('review.%s.url' % p.name, p.remote.review)
+
+      r = p.revisionExpr
+      if r and not IsId(r):
+        if r.startswith(R_HEADS):
+          r = r[len(R_HEADS):]
+        if r == b:
+          r = '.'
+        gm.SetString('submodule.%s.revision' % p.name, r)
+
+      for c in p.copyfiles:
+        info.append('Moved %s out of %s' % (c.src, p.relpath))
+        c._Copy()
+        p.work_git.rm(c.src)
+        mp.work_git.add(c.dest)
+
+      self.SetRevisionId(p.relpath, p.GetRevisionId())
+    mp.work_git.add('.gitignore', '.gitmodules', '.review')
+    pm.end()
+    for i in info:
+      print >>sys.stderr, i
+
+  def _Unload(self):
+    self._loaded = False
+    self._projects = {}
+    self._revisionIds = None
+    self.branch = None
+
+  def _Load(self):
+    if not self._loaded:
+      f = os.path.join(self.repodir, manifest_xml.LOCAL_MANIFEST_NAME)
+      if os.path.exists(f):
+        print >>sys.stderr, 'warning: ignoring %s' % f
+
+      m = self.manifestProject
+      b = m.CurrentBranch
+      if not b:
+        raise ManifestParseError, 'manifest cannot be on detached HEAD'
+      b = m.GetBranch(b).merge
+      if b.startswith(R_HEADS):
+        b = b[len(R_HEADS):]
+      self.branch = b
+      m.remote.name = self._Remote().name
+
+      self._ParseModules()
+
+      if self.IsMirror:
+        self._AddMetaProjectMirror(self.repoProject)
+        self._AddMetaProjectMirror(self.manifestProject)
+
+      self._loaded = True
+
+  def _ParseModules(self):
+    byPath = dict()
+    for name in self._modules.GetSubSections('submodule'):
+      p = self._ParseProject(name)
+      if self._projects.get(p.name):
+        raise ManifestParseError, 'duplicate project "%s"' % p.name
+      if byPath.get(p.relpath):
+        raise ManifestParseError, 'duplicate path "%s"' % p.relpath
+      self._projects[p.name] = p
+      byPath[p.relpath] = p
+
+    for relpath in self._allRevisionIds.keys():
+      if relpath not in byPath:
+        raise ManifestParseError, \
+          'project "%s" not in .gitmodules' \
+          % relpath
+
+  def _Remote(self):
+    m = self.manifestProject
+    b = m.GetBranch(m.CurrentBranch)
+    return b.remote
+
+  def _ResolveUrl(self, url):
+    if url.startswith('./') or url.startswith('../'):
+      base = self._Remote().url
+      try:
+        base = base[:base.rindex('/')+1]
+      except ValueError:
+        base = base[:base.rindex(':')+1]
+      if url.startswith('./'):
+        url = url[2:]
+      while '/' in base and url.startswith('../'):
+        base = base[:base.rindex('/')+1]
+        url = url[3:]
+      return base + url
+    return url
+
+  def _GetRevisionId(self, path):
+    return self._allRevisionIds.get(path)
+
+  @property
+  def _allRevisionIds(self):
+    if self._revisionIds is None:
+      a = dict()
+      p = GitCommand(self.manifestProject,
+                     ['ls-files','-z','--stage'],
+                     capture_stdout = True)
+      for line in p.process.stdout.read().split('\0')[:-1]:
+        l_info, l_path = line.split('\t', 2)
+        l_mode, l_id, l_stage = l_info.split(' ', 2)
+        if l_mode == GITLINK and l_stage == '0':
+          a[l_path] = l_id
+      p.Wait()
+      self._revisionIds = a
+    return self._revisionIds
+
+  def SetRevisionId(self, path, id):
+    self.manifestProject.work_git.update_index(
+      '--add','--cacheinfo', GITLINK, id, path)
+
+  def _ParseProject(self, name):
+    gm = self._modules
+    gr = self._review
+
+    path = gm.GetString('submodule.%s.path' % name)
+    if not path:
+      path = name
+
+    revId = self._GetRevisionId(path)
+    if not revId:
+      raise ManifestParseError(
+        'submodule "%s" has no revision at "%s"' \
+        % (name, path))
+
+    url = gm.GetString('submodule.%s.url' % name)
+    if not url:
+      url = name
+    url = self._ResolveUrl(url)
+
+    review = gr.GetString('review.%s.url' % name)
+    if not review:
+      review = gr.GetString('review.url')
+    if not review:
+      review = self._Remote().review
+
+    remote = RemoteSpec(self._Remote().name, url, review)
+    revExpr = gm.GetString('submodule.%s.revision' % name)
+    if revExpr == '.':
+      revExpr = self.branch
+
+    if self.IsMirror:
+      relpath = None
+      worktree = None
+      gitdir = os.path.join(self.topdir, '%s.git' % name)
+    else:
+      worktree = os.path.join(self.topdir, path)
+      gitdir = os.path.join(self.repodir, 'projects/%s.git' % name)
+
+    return Project(manifest = self,
+                   name = name,
+                   remote = remote,
+                   gitdir = gitdir,
+                   worktree = worktree,
+                   relpath = path,
+                   revisionExpr = revExpr,
+                   revisionId = revId)
+
+  def _AddMetaProjectMirror(self, m):
+    m_url = m.GetRemote(m.remote.name).url
+    if m_url.endswith('/.git'):
+      raise ManifestParseError, 'refusing to mirror %s' % m_url
+
+    name = self._GuessMetaName(m_url)
+    if name.endswith('.git'):
+      name = name[:-4]
+
+    if name not in self._projects:
+      m.PreSync()
+      gitdir = os.path.join(self.topdir, '%s.git' % name)
+      project = Project(manifest = self,
+                        name = name,
+                        remote = RemoteSpec(self._Remote().name, m_url),
+                        gitdir = gitdir,
+                        worktree = None,
+                        relpath = None,
+                        revisionExpr = m.revisionExpr,
+                        revisionId = None)
+      self._projects[project.name] = project
+
+  def _GuessMetaName(self, m_url):
+    parts = m_url.split('/')
+    name = parts[-1]
+    parts = parts[0:-1]
+    s = len(parts) - 1
+    while s > 0:
+      l = '/'.join(parts[0:s]) + '/'
+      r = '/'.join(parts[s:]) + '/'
+      for p in self._projects.values():
+        if p.name.startswith(r) and p.remote.url.startswith(l):
+          return r + name
+      s -= 1
+    return m_url[m_url.rindex('/') + 1:]
