diff --git a/git/index/base.py b/git/index/base.py
index f80eb290d..3e68f843c 100644
--- a/git/index/base.py
+++ b/git/index/base.py
@@ -380,9 +380,17 @@ def raise_exc(e):
 
             # resolve globs if possible
             if '?' in path or '*' in path or '[' in path:
-                for f in self._iter_expand_paths(glob.glob(abs_path)):
-                    yield f.replace(rs, '')
-                continue
+                resolved_paths = glob.glob(abs_path)
+                # not abs_path in resolved_paths:
+                #   a glob() resolving to the same path we are feeding it with
+                #   is a glob() that failed to resolve. If we continued calling
+                #   ourselves we'd endlessly recurse. If the condition below
+                #   evaluates to true then we are likely dealing with a file
+                #   whose name contains wildcard characters.
+                if abs_path not in resolved_paths:
+                    for f in self._iter_expand_paths(glob.glob(abs_path)):
+                        yield f.replace(rs, '')
+                    continue
             # END glob handling
             try:
                 for root, dirs, files in os.walk(abs_path, onerror=raise_exc):
diff --git a/git/test/test_index.py b/git/test/test_index.py
index a928fe5e7..f5f9d7073 100644
--- a/git/test/test_index.py
+++ b/git/test/test_index.py
@@ -796,3 +796,14 @@ def test_add_utf8P_path(self, rw_dir):
         r = Repo.init(rw_dir)
         r.index.add([fp])
         r.index.commit('Added orig and prestable')
+
+    @with_rw_directory
+    def test_add_a_file_with_wildcard_chars(self, rw_dir):
+        # see issue #407
+        fp = os.path.join(rw_dir, '[.exe')
+        with open(fp, "wb") as f:
+            f.write(b'something')
+
+        r = Repo.init(rw_dir)
+        r.index.add([fp])
+        r.index.commit('Added [.exe')