diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,10 @@
+Darcs 2.14.1, 24 June 2018
+
+  * Some dependency bumps (Ganesh Sittampalam, Ben Franksen, Guillaume Hoffmann)
+  * Windows test fixes (Ganesh)
+  * Fixed the following bugs:
+    * 2588 clone creates target repo with wrong permissions (Ben)
+
 Darcs 2.14.0, 4 April 2018
 
   * fix encoding business, make DARCS_DONT_ESCAPE_8BIT=1 default (Ben, Ganesh Sittampalam)
diff --git a/darcs.cabal b/darcs.cabal
--- a/darcs.cabal
+++ b/darcs.cabal
@@ -1,5 +1,5 @@
 Name:           darcs
-version:        2.14.0
+version:        2.14.1
 License:        GPL-2
 License-file:   COPYING
 Author:         David Roundy <droundy@darcs.net>, <darcs-devel@darcs.net>
@@ -382,15 +382,15 @@
 
     build-depends:    base              >= 4.9 && < 4.12,
                       stm               >= 2.1 && < 2.5,
-                      binary            >= 0.5 && < 0.9,
-                      containers        >= 0.5.6.2 && < 0.6,
+                      binary            >= 0.5 && < 0.10,
+                      containers        >= 0.5.6.2 && < 0.7,
                       regex-compat-tdfa >= 0.95.1 && < 0.96,
                       regex-applicative >= 0.2 && < 0.4,
                       mtl               >= 2.2.1 && < 2.3,
                       transformers      >= 0.4.2.0 && < 0.6,
                       parsec            >= 3.1.9 && < 3.2,
-                      fgl               >= 5.5.2.3 && < 5.6,
-                      graphviz          >= 2999.18.1 && < 2999.20,
+                      fgl               >= 5.5.2.3 && < 5.7,
+                      graphviz          >= 2999.18.1 && < 2999.20.1,
                       html              >= 1.0.1.2 && < 1.1,
                       filepath          >= 1.4.1 && < 1.5.0.0,
                       haskeline         >= 0.7.2 && < 0.8,
@@ -402,15 +402,14 @@
                       data-ordlist      == 0.4.*,
                       attoparsec        >= 0.13.0.1 && < 0.14,
                       zip-archive       >= 0.3 && < 0.4,
-                      async             >= 2.0.2 && < 2.2,
+                      async             >= 2.0.2 && < 2.3,
                       sandi             >= 0.4 && < 0.5,
                       unix-compat       >= 0.4.2 && < 0.6,
                       bytestring        >= 0.10.6 && < 0.11,
                       old-time          >= 1.1.0.3 && < 1.2,
-                      time              >= 1.5.0.1 && < 1.9,
+                      time              >= 1.5.0.1 && < 1.10,
                       text              >= 1.2.1.3 && < 1.3,
                       directory         >= 1.2.6.2 && < 1.4,
-                      temporary         >= 1.2.0.4 && < 1.3,
                       process           >= 1.2.3.0 && < 1.7,
                       array             >= 0.5.1.0 && < 0.6,
                       random            >= 1.1 && < 1.2,
@@ -418,7 +417,7 @@
                       mmap              >= 0.5.9 && < 0.6,
                       zlib              >= 0.6.1.2 && < 0.7.0.0,
                       network-uri       == 2.6.*,
-                      network           == 2.6.*,
+                      network           >= 2.6 && < 2.8,
                       HTTP              >= 4000.2.20 && < 4000.4
 
     if flag(optimize)
@@ -522,20 +521,24 @@
                     array        >= 0.5.1.0 && < 0.6,
                     bytestring   >= 0.10.6 && < 0.11,
                     cmdargs      >= 0.10.10 && < 0.11,
-                    containers   >= 0.5.6.2 && < 0.6,
+                    containers   >= 0.5.6.2 && < 0.7,
                     filepath     >= 1.4.1 && < 1.5.0.0,
                     mtl          >= 2.2.1 && < 2.3,
-                    shelly       >= 1.6.8 && < 1.7,
+                    shelly       >= 1.6.8 && < 1.9,
                     split        >= 0.2.2 && < 0.3,
                     text         >= 1.2.1.3 && < 1.3,
                     directory    >= 1.2.6.2 && < 1.4,
                     FindBin      >= 0.0.5 && < 0.1,
-                    QuickCheck   >= 2.8.2 && < 2.11,
+                    QuickCheck   >= 2.8.2 && < 2.12,
                     HUnit        >= 1.3 && < 1.7,
                     test-framework             >= 0.8.1.1 && < 0.9,
                     test-framework-hunit       >= 0.3.0.2 && < 0.4,
                     test-framework-quickcheck2 >= 0.3.0.3 && < 0.4,
                     zip-archive  >= 0.3 && < 0.4
+
+  -- https://github.com/yesodweb/Shelly.hs/issues/177
+  if os(windows)
+    build-depends: shelly < 1.7.2
 
   -- list all unit test modules not exported by libdarcs; otherwise Cabal won't
   -- include them in the tarball
diff --git a/release/distributed-context b/release/distributed-context
--- a/release/distributed-context
+++ b/release/distributed-context
@@ -1,1 +1,1 @@
-Just "\nContext:\n\n[branch-2.14: disable network tests\nGuillaume Hoffmann <guillaumh@gmail.com>**20180404141317\n Ignore-this: 8d6e4b0590002fbe7b0a1d1299d4b\n] \n\n[branch-2.14: fix cabal sdist on newer Cabals\nGuillaume Hoffmann <guillaumh@gmail.com>**20180404141206\n Ignore-this: 69de5e3a3c40f4fc94536db0e7f276a9\n The trick we found is to remove other-modules: Version from\n the darcs executable.\n] \n\n[TAG 2.14.0\nGuillaume Hoffmann <guillaumh@gmail.com>**20180404141149\n Ignore-this: 6181e294bb45bb98b7c9e481990534c0\n] \n"
+Just "\nContext:\n\n[TAG 2.14.1\nGanesh Sittampalam <ganesh@earth.li>**20180624165311\n Ignore-this: 5df6cb67e1a02b11e128e15877e4d206\n] \n"
diff --git a/release/distributed-version b/release/distributed-version
--- a/release/distributed-version
+++ b/release/distributed-version
@@ -1,1 +1,1 @@
-Just 2
+Just 0
diff --git a/src/Darcs/Repository/State.hs b/src/Darcs/Repository/State.hs
--- a/src/Darcs/Repository/State.hs
+++ b/src/Darcs/Repository/State.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 -- Copyright (C) 2009 Petr Rockai
 --           (C) 2012 José Neder
 --
@@ -49,7 +50,7 @@
 import Text.Regex( matchRegex )
 
 import System.Directory( removeFile, doesFileExist, doesDirectoryExist, renameFile )
-import System.FilePath ( (</>) )
+import System.FilePath ( (</>), (<.>) )
 import qualified Data.ByteString as B
     ( ByteString, readFile, drop, writeFile, empty, concat )
 import qualified Data.ByteString.Char8 as BC
@@ -423,7 +424,14 @@
   formatValid <- if exists
                      then I.indexFormatValid index_file
                      else return True
-  when (exists && not formatValid) $ removeFile index_file
+  when (exists && not formatValid) $ do
+-- TODO this conditional logic (rename or delete) is mirrored in
+-- Darcs.Util.Index.updateIndexFrom and should be refactored
+#if mingw32_HOST_OS
+    renameFile index_file (index_file <.> "old")
+#else
+    removeFile index_file
+#endif
   return (invalid, exists, formatValid)
 
 -- |Remove any patches (+dependencies) from a sequence that
diff --git a/src/Darcs/Util/Index.hs b/src/Darcs/Util/Index.hs
--- a/src/Darcs/Util/Index.hs
+++ b/src/Darcs/Util/Index.hs
@@ -514,6 +514,8 @@
        let len_root = itemAllocSize anchoredRoot
            len = len_root + sum [ itemAllocSize p | (p, _) <- list reference ]
        exist <- doesFileExist indexpath
+-- TODO this conditional logic (rename or delete) is mirrored in
+-- Darcs.Repository.State.checkIndex and should be refactored
 #if mingw32_HOST_OS
        when exist $ renameFile indexpath (indexpath <.> "old")
 #else
diff --git a/src/Darcs/Util/Lock.hs b/src/Darcs/Util/Lock.hs
--- a/src/Darcs/Util/Lock.hs
+++ b/src/Darcs/Util/Lock.hs
@@ -63,11 +63,9 @@
     )
 import System.IO.Error
     ( isAlreadyExistsError
-    , alreadyExistsErrorType
     , annotateIOError
-    , mkIOError
+    , catchIOError
     )
-import System.IO.Temp ( withTempDirectory )
 import Control.Exception
     ( IOException
     , bracket
@@ -84,10 +82,9 @@
     , getDirectoryContents
     , createDirectory
     , getTemporaryDirectory
-    , renameDirectory
+    , removeDirectoryRecursive
     )
 import System.FilePath.Posix ( splitDirectories )
-import qualified System.FilePath as NativeFilePath ( takeDirectory )
 import System.Environment ( lookupEnv )
 
 import Control.Concurrent ( threadDelay )
@@ -413,17 +410,12 @@
               -> IOException
 addToErrorLoc ioe s = annotateIOError ioe s Nothing Nothing
 
--- | Do an action in a newly created directory of the given name. The directory
--- is first created with a different temporary name (but under the same parent
--- directory), and becomes renamed to the final name when the action returns
--- without an exception. This operation raises an alreadyExists exception if a
--- file system object of the given name already exists.
+-- | Do an action in a newly created directory of the given name. If the
+-- directory is successfully created but the action raises an exception, the
+-- directory and all its content is deleted. Caught exceptions are re-thrown.
 withNewDirectory :: FilePath -> IO () -> IO ()
 withNewDirectory name action = do
-  exists1 <- doesFileExist name        -- TODO when depending on directory >= 1.2.7
-  exists2 <- doesDirectoryExist name   --      just use doesPathExist
-  when (exists1 || exists2) $
-    throwIO (mkIOError alreadyExistsErrorType name Nothing Nothing)
-  withTempDirectory (NativeFilePath.takeDirectory name) "darcs_new" $ \path -> do
-    withCurrentDirectory path action
-    renameDirectory path name
+  createDirectory name
+  withCurrentDirectory name action `catch` \e -> do
+    removeDirectoryRecursive name `catchIOError` (const $ return ())
+    throwIO (e :: SomeException)
diff --git a/src/Darcs/Util/Path.hs b/src/Darcs/Util/Path.hs
--- a/src/Darcs/Util/Path.hs
+++ b/src/Darcs/Util/Path.hs
@@ -106,7 +106,7 @@
 import qualified Darcs.Util.Workaround as Workaround ( getCurrentDirectory )
 import qualified System.Directory ( setCurrentDirectory )
 import System.Directory ( doesDirectoryExist, doesFileExist )
-import qualified System.FilePath.Posix as FilePath ( normalise )
+import qualified System.FilePath.Posix as FilePath ( normalise, isRelative )
 import qualified System.FilePath as NativeFilePath ( takeFileName, takeDirectory )
 import System.FilePath( (</>), splitDirectories, normalise, dropTrailingPathSeparator )
 import System.Posix.Files ( isDirectory, getSymbolicLinkStatus )
@@ -498,6 +498,12 @@
   * Would it be worth adding a --semi-safe-paths option for allowing
     changes to certain preference files (_darcs\/prefs\/) in sub
     repositories'?
+
+  TODO:
+    Properly review the way we handle paths on Windows - it's not enough
+    to just use the OS native concept of path separator. Windows often
+    accepts both path separators, and repositories always use the UNIX
+    separator anyway.
 -}
 isMaliciousPath :: String -> Bool
 isMaliciousPath fp =
@@ -508,7 +514,7 @@
 --   don't start with ./
 isMaliciousSubPath :: String -> Bool
 isMaliciousSubPath fp =
-    not (isRelative fp) || isGenerallyMalicious fp
+    not (FilePath.isRelative fp) || isGenerallyMalicious fp
 
 isGenerallyMalicious :: String -> Bool
 isGenerallyMalicious fp =
diff --git a/tests/git_import_delete_empty_directories.sh b/tests/git_import_delete_empty_directories.sh
--- a/tests/git_import_delete_empty_directories.sh
+++ b/tests/git_import_delete_empty_directories.sh
@@ -36,8 +36,8 @@
 reset refs/heads/master
 commit refs/heads/master
 mark :2
-author test <test@example.org> 0 +0000
-committer test <test@example.org> 0 +0000
+author test <test@example.org> 1500000000 +0000
+committer test <test@example.org> 1500000000 +0000
 data 19
 Add files and dirs
 M 100644 :1 file
@@ -46,8 +46,8 @@
 
 commit refs/heads/master
 mark :3
-author test <test@example.org> 0 +0000
-committer test <test@example.org> 0 +0000
+author test <test@example.org> 1500000000 +0000
+committer test <test@example.org> 1500000000 +0000
 data 12
 remove foo2
 from :2
@@ -55,8 +55,8 @@
 
 commit refs/heads/master
 mark :4
-author test <test@example.org> 0 +0000
-committer test <test@example.org> 0 +0000
+author test <test@example.org> 1500000000 +0000
+committer test <test@example.org> 1500000000 +0000
 data 21
 Delete foo1 and file
 from :3
diff --git a/tests/git_quoted_filenames.sh b/tests/git_quoted_filenames.sh
--- a/tests/git_quoted_filenames.sh
+++ b/tests/git_quoted_filenames.sh
@@ -45,6 +45,12 @@
 
 commitMsg="some files and dirs that need quoting"
 
+# Filenames containing double quotes are forbidden in Windows 10
+# Although they can be written using raw NTFS APIs, it's probably
+# not worth trying to support them. IO operations in the standard
+# Haskell library don't support them either.
+# https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
+abort_windows
 
 # only run if git present
 git --version | grep -i "git version"   || exit 200
diff --git a/tests/issue2262-display_of_meta_data.sh b/tests/issue2262-display_of_meta_data.sh
--- a/tests/issue2262-display_of_meta_data.sh
+++ b/tests/issue2262-display_of_meta_data.sh
@@ -1,6 +1,9 @@
 #!/usr/bin/env bash
 
 . lib
+
+abort_windows # issue2590
+
 darcs init R
 cd R
 touch äöüßÄÖÜ
diff --git a/tests/latin9-input.sh b/tests/latin9-input.sh
--- a/tests/latin9-input.sh
+++ b/tests/latin9-input.sh
@@ -89,8 +89,10 @@
 
 darcs record -a -A 'Jérôme Leb½uf' -m 'that will be ¤ 15, sir'
 
-grep_changes 'that will be â¬ 15, sir' 'patch name from command line'
-grep_changes 'JÃ©rÃ´me LebÅuf' 'patch author from command line'
+if echo $OS | not grep -i windows; then # issue2591
+    grep_changes 'that will be â¬ 15, sir' 'patch name from command line'
+    grep_changes 'JÃ©rÃ´me LebÅuf' 'patch author from command line'
+fi
 
 # Test recording funny metadata from a log file
 
@@ -109,7 +111,9 @@
 echo 'La la la, the more lines the better!' >> something.txt
 darcs record -a -m 'Patch names are overrated'
 
-grep_changes 'Slavoj Å½iÅ¾ek' 'author name from environment'
+if echo $OS | not grep -i windows; then # issue2591
+    grep_changes 'Slavoj Å½iÅ¾ek' 'author name from environment'
+fi
 
 # Test recording funny metadata from prefs files
 echo '´ed is dead' > _darcs/prefs/author
@@ -121,7 +125,9 @@
 # Test amend-recording funny metadata
 echo 'No, it is really 484' >> something.txt
 echo y | darcs amend-record -p 'Patch by ' -A '´ed is even deader' -a
-grep_changes 'Å½ed is even deader' 'author name from amend-record command line flag'
+if echo $OS | not grep -i windows; then # issue2591
+    grep_changes 'Å½ed is even deader' 'author name from amend-record command line flag'
+fi
 
 cat <<FAKE > editor.hs # create an 'editor' that writes latin9
 import System.Environment
@@ -131,15 +137,19 @@
 FAKE
 ghc --make -o editor editor.hs
 export DARCS_EDITOR="`pwd`/editor"
-printf "y\ny\n" | darcs amend --edit -p 'Patch by '
-grep_changes 'All my â¬s are gone' 'description edited from amend-record'
-grep_changes 'Å½ed is even deader' 'author name taken from draft in amend'
+if echo $OS | not grep -i windows; then # issue2591
+    printf "y\ny\n" | darcs amend --edit -p 'Patch by '
+    grep_changes 'All my â¬s are gone' 'description edited from amend-record'
+    grep_changes 'Å½ed is even deader' 'author name taken from draft in amend'
+fi
 
 # Test tag recording funny metadata
 rm _darcs/prefs/author # Make tag be taken from EMAIL env variable
-darcs tag -m '´ is my favorite letter'
-grep_changes 'Slavoj Å½iÅ¾ek' 'author name from environment with tag command' 1
-grep_changes 'Å½ is my favorite letter' 'Tag name from command line'
+if echo $OS | not grep -i windows; then # issue2591
+    darcs tag -m '´ is my favorite letter'
+    grep_changes 'Slavoj Å½iÅ¾ek' 'author name from environment with tag command' 1
+    grep_changes 'Å½ is my favorite letter' 'Tag name from command line'
+fi
 
 unset EMAIL
 printf "´ors\ninitialcomment\n" | darcs tag --edit-long-comment
@@ -154,9 +164,11 @@
 fi
 rm $HOME/.darcs/author
 
-darcs tag -A Ad¸e -m 'La¸t call'
-grep_changes AdÅ¾e 'Author name from tag command line' 1
-grep_changes 'LaÅ¾t call' 'Tag name from tag command line (take 2)' 1
+if echo $OS | not grep -i windows; then # issue2591
+    darcs tag -A Ad¸e -m 'La¸t call'
+    grep_changes AdÅ¾e 'Author name from tag command line' 1
+    grep_changes 'LaÅ¾t call' 'Tag name from tag command line (take 2)' 1
+fi
 
 cd ..
 
diff --git a/tests/send-external.sh b/tests/send-external.sh
--- a/tests/send-external.sh
+++ b/tests/send-external.sh
@@ -1,6 +1,11 @@
 #!/usr/bin/env bash
 . ./lib
 
+# The argument quoting in the test script below breaks on Windows paths
+# Actually sending email from Windows is very unlikely anyway, so just
+# skip this test.
+abort_windows
+
 DARCS_EDITOR=echo
 export DARCS_EDITOR
 
diff --git a/tests/show_tags.sh b/tests/show_tags.sh
--- a/tests/show_tags.sh
+++ b/tests/show_tags.sh
@@ -29,7 +29,7 @@
 1.0
 EOF
 
-cmp my ref
+diff --strip-trailing-cr my ref
 cd ..
 
 rm -rf temp1
