diff --git a/.appveyor.yml b/.appveyor.yml
index 69b7fe567..5a96f878e 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -46,7 +46,7 @@ install:
         echo %PATH%
         uname -a
         git --version
-        where git git-daemon python pip pip3 pip34
+        where git git-daemon python pip pip3 pip34 sh
         python --version
         python -c "import struct; print(struct.calcsize('P') * 8)"
 
@@ -91,3 +91,11 @@ test_script:
 
 on_success:
     - IF "%PYTHON_VERSION%" == "3.5" IF NOT "%IS_CYGWIN%" == "yes" (codecov)
+
+# Enable this to be able to login to the build worker. You can use the
+# `remmina` program in Ubuntu, use the login information that the line below
+# prints into the log.
+#on_finish:
+#    - |
+#        echo "Running on_finish to establish connection back to the instance"
+#    - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
diff --git a/AUTHORS b/AUTHORS
index 6f93b20d1..b5f0ebdc1 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -25,5 +25,6 @@ Contributors are:
 -Piotr Babij <piotr.babij _at_ gmail.com>
 -Mikuláš Poul <mikulaspoul _at_ gmail.com>
 -Charles Bouchard-Légaré <cblegare.atl _at_ ntis.ca>
+-Yaroslav Halchenko <debian _at_ onerussian.com>
 
 Portions derived from other open source works and are clearly marked.
diff --git a/VERSION b/VERSION
index 399088bf4..04b10b4f1 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.1.6
+2.1.7
diff --git a/git/compat.py b/git/compat.py
index b80458576..b63768f3d 100644
--- a/git/compat.py
+++ b/git/compat.py
@@ -309,5 +309,5 @@ def register_surrogateescape():
 
 try:
     b"100644 \x9f\0aaa".decode(defenc, "surrogateescape")
-except:
+except Exception:
     register_surrogateescape()
diff --git a/git/config.py b/git/config.py
index 7d962276e..3310db890 100644
--- a/git/config.py
+++ b/git/config.py
@@ -424,7 +424,8 @@ def read(self):
                     if include_path in seen or not os.access(include_path, os.R_OK):
                         continue
                     seen.add(include_path)
-                    files_to_read.append(include_path)
+                    # insert included file to the top to be considered first
+                    files_to_read.insert(0, include_path)
                     num_read_include_files += 1
                 # each include path in configuration file
             # end handle includes
diff --git a/git/diff.py b/git/diff.py
index 16c782f3a..28c10e49e 100644
--- a/git/diff.py
+++ b/git/diff.py
@@ -313,20 +313,20 @@ def __str__(self):
             h %= self.b_blob.path
 
         msg = ''
-        l = None    # temp line
-        ll = 0      # line length
+        line = None          # temp line
+        line_length = 0      # line length
         for b, n in zip((self.a_blob, self.b_blob), ('lhs', 'rhs')):
             if b:
-                l = "\n%s: %o | %s" % (n, b.mode, b.hexsha)
+                line = "\n%s: %o | %s" % (n, b.mode, b.hexsha)
             else:
-                l = "\n%s: None" % n
+                line = "\n%s: None" % n
             # END if blob is not None
-            ll = max(len(l), ll)
-            msg += l
+            line_length = max(len(line), line_length)
+            msg += line
         # END for each blob
 
         # add headline
-        h += '\n' + '=' * ll
+        h += '\n' + '=' * line_length
 
         if self.deleted_file:
             msg += '\nfile deleted in rhs'
diff --git a/git/exc.py b/git/exc.py
index a737110c8..4865da944 100644
--- a/git/exc.py
+++ b/git/exc.py
@@ -48,7 +48,7 @@ def __init__(self, command, status=None, stderr=None, stdout=None):
             else:
                 try:
                     status = u'exit code(%s)' % int(status)
-                except:
+                except (ValueError, TypeError):
                     s = safe_decode(str(status))
                     status = u"'%s'" % s if isinstance(status, string_types) else s
 
diff --git a/git/refs/log.py b/git/refs/log.py
index 623a63db1..1c085ef18 100644
--- a/git/refs/log.py
+++ b/git/refs/log.py
@@ -246,7 +246,7 @@ def to_file(self, filepath):
         try:
             self._serialize(fp)
             lfd.commit()
-        except:
+        except Exception:
             # on failure it rolls back automatically, but we make it clear
             lfd.rollback()
             raise
diff --git a/git/remote.py b/git/remote.py
index 35460f5a8..813566a23 100644
--- a/git/remote.py
+++ b/git/remote.py
@@ -542,9 +542,11 @@ def urls(self):
                         if '  Push  URL:' in line:
                             yield line.split(': ')[-1]
                 except GitCommandError as ex:
-                    if any([msg in str(ex) for msg in ['correct access rights','cannot run ssh']]):
-                        # If ssh is not setup to access this repository, see issue 694                                                                                            
-                        result = Git().execute(['git','config','--get','remote.%s.url' % self.name])
+                    if any([msg in str(ex) for msg in ['correct access rights', 'cannot run ssh']]):
+                        # If ssh is not setup to access this repository, see issue 694
+                        result = Git().execute(
+                            ['git', 'config', '--get', 'remote.%s.url' % self.name]
+                        )
                         yield result
                     else:
                         raise ex
diff --git a/git/repo/base.py b/git/repo/base.py
index 990def64c..2fbae0122 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -203,7 +203,7 @@ def __exit__(self, exc_type, exc_value, traceback):
     def __del__(self):
         try:
             self.close()
-        except:
+        except Exception:
             pass
 
     def close(self):
diff --git a/git/test/fixtures/git_config b/git/test/fixtures/git_config
index c9945cd50..b8c178e3f 100644
--- a/git/test/fixtures/git_config
+++ b/git/test/fixtures/git_config
@@ -22,11 +22,25 @@
 	url = git://gitorious.org/~martin.marcher/git-python/serverhorror.git
 	fetch = +refs/heads/*:refs/remotes/MartinMarcher/*
     # can handle comments - the section name is supposed to be stripped
+# causes stock git-config puke
 [  gui ]
 	geometry = 1316x820+219+243 207 192
 [branch "mainline_performance"]
 	remote = mainline
 	merge = refs/heads/master
+# section with value defined before include to be overriden
+[sec]
+    var0 = value0_main
 [include]
-	path = doesntexist.cfg
-	abspath = /usr/bin/foodoesntexist.bar
\ No newline at end of file
+    path = doesntexist.cfg
+    # field should be 'path' so abspath should be ignored
+    abspath = /usr/bin/foodoesntexist.bar
+    path = /usr/bin/foodoesntexist.bar
+    # should be relative to the path of this config file
+    path = ./git_config-inc.cfg
+# and defined after include.  According to the documentation
+# and behavior of git config, this should be the value since
+# inclusions should be processed immediately
+[sec]
+    var1 = value1_main
+
diff --git a/git/test/fixtures/git_config-inc.cfg b/git/test/fixtures/git_config-inc.cfg
new file mode 100644
index 000000000..2368ec20c
--- /dev/null
+++ b/git/test/fixtures/git_config-inc.cfg
@@ -0,0 +1,5 @@
+[sec]
+    var0 = value0_included
+    var1 = value1_included
+[diff]
+    tool = diff_included
diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py
index 729c76a4f..cb46173dc 100644
--- a/git/test/lib/helper.py
+++ b/git/test/lib/helper.py
@@ -29,6 +29,8 @@
     import unittest
 
 TestCase = unittest.TestCase
+SkipTest = unittest.SkipTest
+skipIf = unittest.skipIf
 
 ospd = osp.dirname
 
@@ -37,7 +39,9 @@
 
 __all__ = (
     'fixture_path', 'fixture', 'StringProcessAdapter',
-    'with_rw_directory', 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase',
+    'with_rw_directory', 'with_rw_repo', 'with_rw_and_rw_remote_repo',
+    'TestBase', 'TestCase',
+    'SkipTest', 'skipIf',
     'GIT_REPO', 'GIT_DAEMON_PORT'
 )
 
@@ -139,7 +143,7 @@ def repo_creator(self):
             try:
                 try:
                     return func(self, rw_repo)
-                except:
+                except:  # noqa E722
                     log.info("Keeping repo after failure: %s", repo_dir)
                     repo_dir = None
                     raise
@@ -227,7 +231,7 @@ def with_rw_and_rw_remote_repo(working_tree_ref):
     Same as with_rw_repo, but also provides a writable remote repository from which the
     rw_repo has been forked as well as a handle for a git-daemon that may be started to
     run the remote_repo.
-    The remote repository was cloned as bare repository from the rorepo, whereas
+    The remote repository was cloned as bare repository from the ro repo, whereas
     the rw repo has a working tree and was cloned from the remote repository.
 
     remote_repo has two remotes: origin and daemon_origin. One uses a local url,
@@ -296,7 +300,7 @@ def remote_repo_creator(self):
                     with cwd(rw_repo.working_dir):
                         try:
                             return func(self, rw_repo, rw_daemon_repo)
-                        except:
+                        except:  # noqa E722
                             log.info("Keeping repos after failure: \n  rw_repo_dir: %s \n  rw_daemon_repo_dir: %s",
                                      rw_repo_dir, rw_daemon_repo_dir)
                             rw_repo_dir = rw_daemon_repo_dir = None
diff --git a/git/test/test_commit.py b/git/test/test_commit.py
index fbb1c244e..cd6c5d5f6 100644
--- a/git/test/test_commit.py
+++ b/git/test/test_commit.py
@@ -169,8 +169,7 @@ def test_traversal(self):
         # at some point, both iterations should stop
         self.assertEqual(list(bfirst)[-1], first)
         stoptraverse = self.rorepo.commit("254d04aa3180eb8b8daf7b7ff25f010cd69b4e7d").traverse(as_edge=True)
-        l = list(stoptraverse)
-        self.assertEqual(len(l[0]), 2)
+        self.assertEqual(len(next(stoptraverse)), 2)
 
         # ignore self
         self.assertEqual(next(start.traverse(ignore_self=False)), start)
diff --git a/git/test/test_config.py b/git/test/test_config.py
index 7cf9d3173..4d6c82363 100644
--- a/git/test/test_config.py
+++ b/git/test/test_config.py
@@ -15,6 +15,7 @@
 from git.test.lib import (
     TestCase,
     fixture_path,
+    SkipTest,
 )
 from git.test.lib import with_rw_directory
 
@@ -88,6 +89,21 @@ def test_read_write(self):
                 assert r_config.get(sname, oname) == val
         # END for each filename
 
+    def test_includes_order(self):
+        with GitConfigParser(list(map(fixture_path, ("git_config", "git_config_global")))) as r_config:
+            r_config.read()                 # enforce reading
+            # Simple inclusions, again checking them taking precedence
+            assert r_config.get_value('sec', 'var0') == "value0_included"
+            # This one should take the git_config_global value since included
+            # values must be considered as soon as they get them
+            assert r_config.get_value('diff', 'tool') == "meld"
+            try:
+                assert r_config.get_value('sec', 'var1') == "value1_main"
+            except AssertionError:
+                raise SkipTest(
+                    'Known failure -- included values are not in effect right away'
+                )
+
     @with_rw_directory
     def test_lock_reentry(self, rw_dir):
         fpl = osp.join(rw_dir, 'l')
diff --git a/git/test/test_git.py b/git/test/test_git.py
index 0a0d7ef74..059f90c0e 100644
--- a/git/test/test_git.py
+++ b/git/test/test_git.py
@@ -37,6 +37,8 @@
 except ImportError:
     import mock
 
+from git.compat import is_win
+
 
 class TestGit(TestBase):
 
@@ -177,7 +179,8 @@ def test_refresh(self):
         self.assertRaises(GitCommandNotFound, refresh, "yada")
 
         # test a good path refresh
-        path = os.popen("which git").read().strip()
+        which_cmd = "where" if is_win else "which"
+        path = os.popen("{0} git".format(which_cmd)).read().strip().split('\n')[0]
         refresh(path)
 
     def test_options_are_passed_to_git(self):
diff --git a/git/test/test_index.py b/git/test/test_index.py
index cf7461408..757bec9f9 100644
--- a/git/test/test_index.py
+++ b/git/test/test_index.py
@@ -54,6 +54,22 @@
 import os.path as osp
 from git.cmd import Git
 
+HOOKS_SHEBANG = "#!/usr/bin/env sh\n"
+
+
+@skipIf(HIDE_WINDOWS_KNOWN_ERRORS, "TODO: fix hooks execution on Windows: #703")
+def _make_hook(git_dir, name, content, make_exec=True):
+    """A helper to create a hook"""
+    hp = hook_path(name, git_dir)
+    hpd = osp.dirname(hp)
+    if not osp.isdir(hpd):
+        os.mkdir(hpd)
+    with open(hp, "wt") as fp:
+        fp.write(HOOKS_SHEBANG + content)
+    if make_exec:
+        os.chmod(hp, 0o744)
+    return hp
+
 
 class TestIndex(TestBase):
 
@@ -834,25 +850,21 @@ def test_add_a_file_with_wildcard_chars(self, rw_dir):
     @with_rw_repo('HEAD', bare=True)
     def test_pre_commit_hook_success(self, rw_repo):
         index = rw_repo.index
-        hp = hook_path('pre-commit', index.repo.git_dir)
-        hpd = osp.dirname(hp)
-        if not osp.isdir(hpd):
-            os.mkdir(hpd)
-        with open(hp, "wt") as fp:
-            fp.write("#!/usr/bin/env sh\nexit 0")
-        os.chmod(hp, 0o744)
+        _make_hook(
+            index.repo.git_dir,
+            'pre-commit',
+            "exit 0"
+        )
         index.commit("This should not fail")
 
     @with_rw_repo('HEAD', bare=True)
     def test_pre_commit_hook_fail(self, rw_repo):
         index = rw_repo.index
-        hp = hook_path('pre-commit', index.repo.git_dir)
-        hpd = osp.dirname(hp)
-        if not osp.isdir(hpd):
-            os.mkdir(hpd)
-        with open(hp, "wt") as fp:
-            fp.write("#!/usr/bin/env sh\necho stdout; echo stderr 1>&2; exit 1")
-        os.chmod(hp, 0o744)
+        hp = _make_hook(
+            index.repo.git_dir,
+            'pre-commit',
+            "echo stdout; echo stderr 1>&2; exit 1"
+        )
         try:
             index.commit("This should fail")
         except HookExecutionError as err:
@@ -869,35 +881,29 @@ def test_pre_commit_hook_fail(self, rw_repo):
                 self.assertEqual(err.stderr, "\n  stderr: 'stderr\n'")
                 assert str(err)
         else:
-            raise AssertionError("Should have cought a HookExecutionError")
+            raise AssertionError("Should have caught a HookExecutionError")
 
     @with_rw_repo('HEAD', bare=True)
     def test_commit_msg_hook_success(self, rw_repo):
-        index = rw_repo.index
         commit_message = u"commit default head by Frèderic Çaufl€"
         from_hook_message = u"from commit-msg"
-
-        hp = hook_path('commit-msg', index.repo.git_dir)
-        hpd = osp.dirname(hp)
-        if not osp.isdir(hpd):
-            os.mkdir(hpd)
-        with open(hp, "wt") as fp:
-            fp.write('#!/usr/bin/env sh\necho -n " {}" >> "$1"'.format(from_hook_message))
-        os.chmod(hp, 0o744)
-
+        index = rw_repo.index
+        _make_hook(
+            index.repo.git_dir,
+            'commit-msg',
+            'echo -n " {0}" >> "$1"'.format(from_hook_message)
+        )
         new_commit = index.commit(commit_message)
-        self.assertEqual(new_commit.message, u"{} {}".format(commit_message, from_hook_message))
+        self.assertEqual(new_commit.message, u"{0} {1}".format(commit_message, from_hook_message))
 
     @with_rw_repo('HEAD', bare=True)
     def test_commit_msg_hook_fail(self, rw_repo):
         index = rw_repo.index
-        hp = hook_path('commit-msg', index.repo.git_dir)
-        hpd = osp.dirname(hp)
-        if not osp.isdir(hpd):
-            os.mkdir(hpd)
-        with open(hp, "wt") as fp:
-            fp.write("#!/usr/bin/env sh\necho stdout; echo stderr 1>&2; exit 1")
-        os.chmod(hp, 0o744)
+        hp = _make_hook(
+            index.repo.git_dir,
+            'commit-msg',
+            "echo stdout; echo stderr 1>&2; exit 1"
+        )
         try:
             index.commit("This should fail")
         except HookExecutionError as err:
diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py
index f970dd2c0..5c8a2798a 100644
--- a/git/test/test_submodule.py
+++ b/git/test/test_submodule.py
@@ -920,4 +920,4 @@ class Repo(object):
         submodule_path = 'D:\\submodule_path'
         relative_path = Submodule._to_relative_path(super_repo, submodule_path)
         msg = '_to_relative_path should be "submodule_path" but was "%s"' % relative_path
-        assert relative_path == 'submodule_path', msg
\ No newline at end of file
+        assert relative_path == 'submodule_path', msg
diff --git a/git/test/test_util.py b/git/test/test_util.py
index 525c86092..d30c8376d 100644
--- a/git/test/test_util.py
+++ b/git/test/test_util.py
@@ -217,49 +217,49 @@ def test_actor(self):
     @ddt.data(('name', ''), ('name', 'prefix_'))
     def test_iterable_list(self, case):
         name, prefix = case
-        l = IterableList(name, prefix)
+        ilist = IterableList(name, prefix)
 
         name1 = "one"
         name2 = "two"
         m1 = TestIterableMember(prefix + name1)
         m2 = TestIterableMember(prefix + name2)
 
-        l.extend((m1, m2))
+        ilist.extend((m1, m2))
 
-        self.assertEqual(len(l), 2)
+        self.assertEqual(len(ilist), 2)
 
         # contains works with name and identity
-        self.assertIn(name1, l)
-        self.assertIn(name2, l)
-        self.assertIn(m2, l)
-        self.assertIn(m2, l)
-        self.assertNotIn('invalid', l)
+        self.assertIn(name1, ilist)
+        self.assertIn(name2, ilist)
+        self.assertIn(m2, ilist)
+        self.assertIn(m2, ilist)
+        self.assertNotIn('invalid', ilist)
 
         # with string index
-        self.assertIs(l[name1], m1)
-        self.assertIs(l[name2], m2)
+        self.assertIs(ilist[name1], m1)
+        self.assertIs(ilist[name2], m2)
 
         # with int index
-        self.assertIs(l[0], m1)
-        self.assertIs(l[1], m2)
+        self.assertIs(ilist[0], m1)
+        self.assertIs(ilist[1], m2)
 
         # with getattr
-        self.assertIs(l.one, m1)
-        self.assertIs(l.two, m2)
+        self.assertIs(ilist.one, m1)
+        self.assertIs(ilist.two, m2)
 
         # test exceptions
-        self.failUnlessRaises(AttributeError, getattr, l, 'something')
-        self.failUnlessRaises(IndexError, l.__getitem__, 'something')
+        self.failUnlessRaises(AttributeError, getattr, ilist, 'something')
+        self.failUnlessRaises(IndexError, ilist.__getitem__, 'something')
 
         # delete by name and index
-        self.failUnlessRaises(IndexError, l.__delitem__, 'something')
-        del(l[name2])
-        self.assertEqual(len(l), 1)
-        self.assertNotIn(name2, l)
-        self.assertIn(name1, l)
-        del(l[0])
-        self.assertNotIn(name1, l)
-        self.assertEqual(len(l), 0)
-
-        self.failUnlessRaises(IndexError, l.__delitem__, 0)
-        self.failUnlessRaises(IndexError, l.__delitem__, 'something')
+        self.failUnlessRaises(IndexError, ilist.__delitem__, 'something')
+        del(ilist[name2])
+        self.assertEqual(len(ilist), 1)
+        self.assertNotIn(name2, ilist)
+        self.assertIn(name1, ilist)
+        del(ilist[0])
+        self.assertNotIn(name1, ilist)
+        self.assertEqual(len(ilist), 0)
+
+        self.failUnlessRaises(IndexError, ilist.__delitem__, 0)
+        self.failUnlessRaises(IndexError, ilist.__delitem__, 'something')
diff --git a/git/util.py b/git/util.py
index 5baeee918..18c28fd17 100644
--- a/git/util.py
+++ b/git/util.py
@@ -188,20 +188,15 @@ def assure_directory_exists(path, is_file=False):
 
 
 def _get_exe_extensions():
-    try:
-        winprog_exts = tuple(p.upper() for p in os.environ['PATHEXT'].split(os.pathsep))
-    except:
-        winprog_exts = ('.BAT', 'COM', '.EXE')
-
-    return winprog_exts
+    PATHEXT = os.environ.get('PATHEXT', None)
+    return tuple(p.upper() for p in PATHEXT.split(os.pathsep)) \
+        if PATHEXT \
+        else (('.BAT', 'COM', '.EXE') if is_win else ())
 
 
 def py_where(program, path=None):
     # From: http://stackoverflow.com/a/377028/548792
-    try:
-        winprog_exts = tuple(p.upper() for p in os.environ['PATHEXT'].split(os.pathsep))
-    except:
-        winprog_exts = is_win and ('.BAT', 'COM', '.EXE') or ()
+    winprog_exts = _get_exe_extensions()
 
     def is_exec(fpath):
         return osp.isfile(fpath) and os.access(fpath, os.X_OK) and (
@@ -347,7 +342,7 @@ def expand_path(p, expand_vars=True):
         if expand_vars:
             p = osp.expandvars(p)
         return osp.normpath(osp.abspath(p))
-    except:
+    except Exception:
         return None
 
 #} END utilities