diff -urN hg-git-0.8.3-orig/hggit/__init__.py hg-git-0.8.3/hggit/__init__.py
--- hg-git-0.8.3-orig/hggit/__init__.py	2015-11-09 14:41:16 +0900
+++ hg-git-0.8.3/hggit/__init__.py	2015-12-19 00:08:21 +0900
@@ -214,7 +214,7 @@
 @command('gimport')
 def gimport(ui, repo, remote_name=None):
     '''import commits from Git to Mercurial'''
-    repo.githandler.import_commits(remote_name)
+    repo.githandler.import_commits()
 
 @command('gexport')
 def gexport(ui, repo):
diff -urN hg-git-0.8.3-orig/hggit/git_handler.py hg-git-0.8.3/hggit/git_handler.py
--- hg-git-0.8.3-orig/hggit/git_handler.py	2015-10-08 05:18:25 +0900
+++ hg-git-0.8.3/hggit/git_handler.py	2015-12-19 00:34:47 +0900
@@ -20,6 +20,8 @@
 from mercurial import bookmarks
 from mercurial import commands
 from mercurial import context, util as hgutil
+from mercurial import error
+from mercurial import hg
 from mercurial import url
 
 import _ssh
@@ -236,10 +238,10 @@
 
     # COMMANDS METHODS
 
-    def import_commits(self, remote_name):
+    def import_commits(self):
         refs = self.git.refs.as_dict()
         filteredrefs = self.filter_min_date(refs)
-        self.import_git_objects(remote_name, filteredrefs)
+        self.import_git_objects(None, filteredrefs)
         self.update_hg_bookmarks(refs)
         self.save_map(self.map_file)
 
@@ -251,7 +253,7 @@
         imported = 0
         if refs:
             filteredrefs = self.filter_min_date(self.filter_refs(refs, heads))
-            imported = self.import_git_objects(remote_name, filteredrefs)
+            imported = self.import_git_objects(remote, filteredrefs)
             self.import_tags(refs)
             self.update_hg_bookmarks(refs)
             if remote_name:
@@ -694,7 +696,7 @@
     def get_git_incoming(self, refs):
         return git2hg.find_incoming(self.git.object_store, self._map_git, refs)
 
-    def import_git_objects(self, remote_name, refs):
+    def import_git_objects(self, remote, refs):
         result = self.get_git_incoming(refs)
         commits = result.commits
         commit_cache = result.commit_cache
@@ -706,10 +708,11 @@
             self.ui.status(_("no changes found\n"))
 
         mapsavefreq = self.ui.configint('hggit', 'mapsavefrequency', 0)
+        imported_submodules = {}
         for i, csha in enumerate(commits):
             self.ui.progress('importing', i, total=total, unit='commits')
             commit = commit_cache[csha]
-            self.import_git_commit(commit)
+            self.import_git_commit(commit, remote, imported_submodules)
             if mapsavefreq and i % mapsavefreq == 0:
                 self.ui.debug(_("saving mapfile\n"))
                 self.save_map(self.map_file)
@@ -718,7 +721,7 @@
         # TODO if the tags cache is used, remove any dangling tag references
         return total
 
-    def import_git_commit(self, commit):
+    def import_git_commit(self, commit, remote, imported_submodules):
         self.ui.debug(_("importing: %s\n") % commit.id)
 
         detect_renames = False
@@ -750,6 +753,48 @@
 
         git_commit_tree = self.git[commit.tree]
 
+        # Analyze .hgsub and merge with .gitmodules
+        hgsub = None
+        gitmodules = self.parse_gitmodules(git_commit_tree)
+        if gitmodules:
+            hgsub = util.parse_hgsub(self.git_file_readlines(git_commit_tree,
+                                                             '.hgsub'))
+            for (sm_path, sm_url, sm_name) in gitmodules:
+                if sm_url.startswith('git+') or sm_url.startswith('git://') or sm_url.startswith('http://') or sm_url.startswith('https://'):
+                    if sm_url.startswith('git+'):
+                        git_url = sm_url
+                    else:
+                        git_url = 'git+' + sm_url
+                    if '//' in remote and git_url.split('//', 1)[1] == remote.split('//', 1)[1]:
+                        self.repo.ui.warn('Skipping import of self-referential submodule %s in commit %s.\n' % (sm_path, commit.id))
+                        continue
+                    else:
+                        hgsub[sm_path] = '[hg]' + git_url
+                        if gitlinks and sm_path in gitlinks:
+                            git_sha = gitlinks[sm_path]
+                            gitlinks[sm_path] = self._map_subrepo_sha(sm_path, git_url, git_sha)
+                            if gitlinks[sm_path]:
+                                hgsub[sm_path] = sm_path
+                            else:
+                                if sm_path not in imported_submodules:
+                                    self.repo.ui.warn('Skipping import of submodule %s (at nonexistent commit %s) in commit %s.\n' % (sm_path, git_sha, commit.id))
+                                elif imported_submodules[sm_path] != git_sha:
+                                    self.repo.ui.warn('Skipping update of submodule %s (to nonexistent commit %s) in commit %s.\n' % (sm_path, git_sha, commit.id))
+                                imported_submodules[sm_path] = git_sha
+                            imported_submodules[sm_path] = git_sha
+                        else:
+                            imported_submodules[sm_path] = None
+                else:
+                    hgsub[sm_path] = '[git]' + sm_url
+            files['.hgsub'] = (False, 0100644, None)
+        elif (commit.parents and '.gitmodules' in
+              self.git[self.git[commit.parents[0]].tree]):
+            # no .gitmodules in this commit, however present in the parent
+            # mark its hg counterpart as deleted (assuming .hgsub is there
+            # due to the same import_git_commit process
+            files['.hgsub'] = (True, 0100644, None)
+
+
         # Analyze hgsubstate and build an updated version using SHAs from
         # gitlinks. Order of application:
         # - preexisting .hgsubstate in git tree
@@ -767,9 +812,7 @@
                 for path, sha in parentsubstate.iteritems():
                     hgsubstate[path] = sha
         for path, sha in gitlinks.iteritems():
-            if sha is None:
-                hgsubstate.pop(path, None)
-            else:
+            if sha is not None:
                 hgsubstate[path] = sha
         # in case .hgsubstate wasn't among changed files
         # force its inclusion if it wasn't already deleted
@@ -781,22 +824,6 @@
         elif util.serialize_hgsubstate(hgsubstate) != parentsubdata:
             files['.hgsubstate'] = False, 0100644, None
 
-        # Analyze .hgsub and merge with .gitmodules
-        hgsub = None
-        gitmodules = self.parse_gitmodules(git_commit_tree)
-        if gitmodules:
-            hgsub = util.parse_hgsub(self.git_file_readlines(git_commit_tree,
-                                                             '.hgsub'))
-            for (sm_path, sm_url, sm_name) in gitmodules:
-                hgsub[sm_path] = '[git]' + sm_url
-            files['.hgsub'] = (False, 0100644, None)
-        elif (commit.parents and '.gitmodules' in
-              self.git[self.git[commit.parents[0]].tree]):
-            # no .gitmodules in this commit, however present in the parent
-            # mark its hg counterpart as deleted (assuming .hgsub is there
-            # due to the same import_git_commit process
-            files['.hgsub'] = (True, 0100644, None)
-
         date = (commit.author_time, -commit.author_timezone)
         text = strip_message
 
@@ -1603,3 +1630,18 @@
 
         # if its not git or git+ssh, try a local url..
         return client.SubprocessGitClient(), uri
+
+    def _map_subrepo_sha(self, path, remote, gitsha):
+        """Return the Mercurial node ID corresponding to the given Git node.
+
+        Assumes path is a repository cloned (or to be cloned) with hg-git.
+        If path does not exist, it is cloned from the given remote repo.
+        """
+        try:
+            subrepo = hg.repository(self.ui, self.repo.wjoin(path))
+        except error.RepoError:
+            self.ui.status(_('cloning submodule %s from %s\n' % (path, remote)))
+            commands.clone(self.ui, remote, self.repo.wjoin(path))
+            subrepo = hg.repository(self.ui, self.repo.wjoin(path))
+        handler = GitHandler(subrepo, self.ui)
+        return handler.map_hg_get(gitsha)
