diff --git a/hgext/convert/__init__.py b/hgext/convert/__init__.py
index 52c552a05414ef6bf001c48c14bb39f25fbfbf31_aGdleHQvY29udmVydC9fX2luaXRfXy5weQ==..daf9f7ee2a5c9b51a9b14decff75cbd7910ea316_aGdleHQvY29udmVydC9fX2luaXRfXy5weQ== 100644
--- a/hgext/convert/__init__.py
+++ b/hgext/convert/__init__.py
@@ -328,6 +328,23 @@
     Mercurial Destination
     #####################
 
+    The Mercurial destination will recognize Mercurial subrepositories in the
+    destination directory, and update the .hgsubstate file automatically if the
+    destination subrepositories contain the <dest>/<sub>/.hg/shamap file.
+    Converting a repository with subrepositories requires converting a single
+    repository at a time, from the bottom up.
+
+    .. container:: verbose
+
+       An example showing how to convert a repository with subrepositories::
+
+         # so convert knows the type when it sees a non empty destination
+         $ hg init converted
+
+         $ hg convert orig/sub1 converted/sub1
+         $ hg convert orig/sub2 converted/sub2
+         $ hg convert orig converted
+
     The following options are supported:
 
     :convert.hg.clonebranches: dispatch source branches in separate
diff --git a/hgext/convert/hg.py b/hgext/convert/hg.py
index 52c552a05414ef6bf001c48c14bb39f25fbfbf31_aGdleHQvY29udmVydC9oZy5weQ==..daf9f7ee2a5c9b51a9b14decff75cbd7910ea316_aGdleHQvY29udmVydC9oZy5weQ== 100644
--- a/hgext/convert/hg.py
+++ b/hgext/convert/hg.py
@@ -23,7 +23,7 @@
 from mercurial.node import bin, hex, nullid
 from mercurial import hg, util, context, bookmarks, error, scmutil, exchange
 
-from common import NoRepo, commit, converter_source, converter_sink
+from common import NoRepo, commit, converter_source, converter_sink, mapfile
 
 import re
 sha1re = re.compile(r'\b[0-9a-f]{12,40}\b')
@@ -59,6 +59,7 @@
         self.lock = None
         self.wlock = None
         self.filemapmode = False
+        self.subrevmaps = {}
 
     def before(self):
         self.ui.debug('run hg sink pre-conversion action\n')
@@ -135,6 +136,45 @@
             fp.write('%s %s\n' % (revid, s[1]))
         return fp.getvalue()
 
+    def _rewritesubstate(self, source, data):
+        fp = cStringIO.StringIO()
+        for line in data.splitlines():
+            s = line.split(' ', 1)
+            if len(s) != 2:
+                continue
+
+            revid = s[0]
+            subpath = s[1]
+            if revid != hex(nullid):
+                revmap = self.subrevmaps.get(subpath)
+                if revmap is None:
+                    revmap = mapfile(self.ui,
+                                     self.repo.wjoin(subpath, '.hg/shamap'))
+                    self.subrevmaps[subpath] = revmap
+
+                    # It is reasonable that one or more of the subrepos don't
+                    # need to be converted, in which case they can be cloned
+                    # into place instead of converted.  Therefore, only warn
+                    # once.
+                    msg = _('no ".hgsubstate" updates will be made for "%s"\n')
+                    if len(revmap) == 0:
+                        sub = self.repo.wvfs.reljoin(subpath, '.hg')
+
+                        if self.repo.wvfs.exists(sub):
+                            self.ui.warn(msg % subpath)
+
+                newid = revmap.get(revid)
+                if not newid:
+                    if len(revmap) > 0:
+                        self.ui.warn(_("%s is missing from %s/.hg/shamap\n") %
+                                     (revid, subpath))
+                else:
+                    revid = newid
+
+            fp.write('%s %s\n' % (revid, subpath))
+
+        return fp.getvalue()
+
     def putcommit(self, files, copies, parents, commit, source, revmap, full,
                   cleanp2):
         files = dict(files)
@@ -152,6 +192,8 @@
                 return None
             if f == '.hgtags':
                 data = self._rewritetags(source, revmap, data)
+            if f == '.hgsubstate':
+                data = self._rewritesubstate(source, data)
             return context.memfilectx(self.repo, f, data, 'l' in mode,
                                       'x' in mode, copies.get(f))
 
diff --git a/tests/test-convert.t b/tests/test-convert.t
index 52c552a05414ef6bf001c48c14bb39f25fbfbf31_dGVzdHMvdGVzdC1jb252ZXJ0LnQ=..daf9f7ee2a5c9b51a9b14decff75cbd7910ea316_dGVzdHMvdGVzdC1jb252ZXJ0LnQ= 100644
--- a/tests/test-convert.t
+++ b/tests/test-convert.t
@@ -279,6 +279,12 @@
       Mercurial Destination
       #####################
   
+      The Mercurial destination will recognize Mercurial subrepositories in the
+      destination directory, and update the .hgsubstate file automatically if
+      the destination subrepositories contain the <dest>/<sub>/.hg/shamap file.
+      Converting a repository with subrepositories requires converting a single
+      repository at a time, from the bottom up.
+  
       The following options are supported:
   
       convert.hg.clonebranches
diff --git a/tests/test-fileset.t b/tests/test-fileset.t
index 52c552a05414ef6bf001c48c14bb39f25fbfbf31_dGVzdHMvdGVzdC1maWxlc2V0LnQ=..daf9f7ee2a5c9b51a9b14decff75cbd7910ea316_dGVzdHMvdGVzdC1maWxlc2V0LnQ= 100644
--- a/tests/test-fileset.t
+++ b/tests/test-fileset.t
@@ -180,7 +180,12 @@
   $ hg -R sub add sub/suba
   $ hg -R sub ci -m sub
   $ echo 'sub = sub' > .hgsub
+  $ hg init sub2
+  $ echo b > sub2/b
+  $ hg -R sub2 ci -Am sub2
+  adding b
+  $ echo 'sub2 = sub2' >> .hgsub
   $ fileset 'subrepo()'
   $ hg add .hgsub
   $ fileset 'subrepo()'
   sub
@@ -183,8 +188,9 @@
   $ fileset 'subrepo()'
   $ hg add .hgsub
   $ fileset 'subrepo()'
   sub
+  sub2
   $ fileset 'subrepo("sub")'
   sub
   $ fileset 'subrepo("glob:*")'
   sub
@@ -187,6 +193,7 @@
   $ fileset 'subrepo("sub")'
   sub
   $ fileset 'subrepo("glob:*")'
   sub
+  sub2
   $ hg ci -m subrepo
 
@@ -191,5 +198,36 @@
   $ hg ci -m subrepo
 
+Test that .hgsubstate is updated as appropriate during a conversion.  The
+saverev property is enough to alter the hashes of the subrepo.
+
+  $ hg init ../converted
+  $ hg --config extensions.convert= convert --config convert.hg.saverev=True  \
+  >      sub ../converted/sub
+  initializing destination ../converted/sub repository
+  scanning source...
+  sorting...
+  converting...
+  0 sub
+  $ hg clone -U sub2 ../converted/sub2
+  $ hg --config extensions.convert= convert --config convert.hg.saverev=True  \
+  >      . ../converted
+  scanning source...
+  sorting...
+  converting...
+  4 addfiles
+  3 manychanges
+  2 diverging
+  1 merge
+  0 subrepo
+  no ".hgsubstate" updates will be made for "sub2"
+  $ hg up -q -R ../converted -r tip
+  $ hg --cwd ../converted cat sub/suba sub2/b -r tip
+  a
+  b
+  $ oldnode=`hg log -r tip -T "{node}\n"`
+  $ newnode=`hg log -R ../converted -r tip -T "{node}\n"`
+  $ [[ "$oldnode" != "$newnode" ]] || echo "nothing changed"
+
 Test with a revision
 
   $ hg log -G --template '{rev} {desc}\n'
@@ -241,6 +279,7 @@
 
   $ fileset -r4 'subrepo("re:su.*")'
   sub
+  sub2
   $ fileset -r4 'subrepo("sub")'
   sub
   $ fileset -r4 'b2 or c1'