vfs: add rmtree
This duplicates "onerror()" function from "svnsubrepo.remove()" for
equivalence of replacing in subsequent patch.
This "onerror()" function for "shutil.rmtree()" was introduced by
92b0d669637f, which avoids failure of removing svn repository on
Windows.
--- a/mercurial/scmutil.py Sat Apr 11 00:47:09 2015 +0900
+++ b/mercurial/scmutil.py Sat Apr 11 00:47:09 2015 +0900
@@ -10,7 +10,7 @@
import util, error, osutil, revset, similar, encoding, phases
import pathutil
import match as matchmod
-import os, errno, re, glob, tempfile
+import os, errno, re, glob, tempfile, shutil, stat
if os.name == 'nt':
import scmwindows as scmplatform
@@ -316,6 +316,26 @@
def readlink(self, path):
return os.readlink(self.join(path))
+ def rmtree(self, path=None, ignore_errors=False, forcibly=False):
+ """Remove a directory tree recursively
+
+ If ``forcibly``, this tries to remove READ-ONLY files, too.
+ """
+ if forcibly:
+ def onerror(function, path, excinfo):
+ if function is not os.remove:
+ raise
+ # read-only files cannot be unlinked under Windows
+ s = os.stat(path)
+ if (s.st_mode & stat.S_IWRITE) != 0:
+ raise
+ os.chmod(path, stat.S_IMODE(s.st_mode) | stat.S_IWRITE)
+ os.remove(path)
+ else:
+ onerror = None
+ return shutil.rmtree(self.join(path),
+ ignore_errors=ignore_errors, onerror=onerror)
+
def setflags(self, path, l, x):
return util.setflags(self.join(path), l, x)