mercurial/subrepo.py
changeset 13016 9efc316a6716
parent 12996 3a42651b0a62
parent 13015 82ca0c43bc44
child 13018 96956105e92d
--- a/mercurial/subrepo.py	Wed Nov 17 09:37:57 2010 +0100
+++ b/mercurial/subrepo.py	Wed Nov 17 21:30:13 2010 +0100
@@ -5,7 +5,8 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import errno, os, re, xml.dom.minidom, shutil, subprocess, urlparse, posixpath
+import errno, os, re, xml.dom.minidom, shutil, urlparse, posixpath
+import stat, subprocess
 from i18n import _
 import config, util, node, error, cmdutil
 hg = None
@@ -480,12 +481,15 @@
         env = dict(os.environ)
         # Avoid localized output, preserve current locale for everything else.
         env['LC_MESSAGES'] = 'C'
-        write, read, err = util.popen3(cmd, env=env, newlines=True)
-        retdata = read.read()
-        err = err.read().strip()
-        if err:
-            raise util.Abort(err)
-        return retdata
+        p = subprocess.Popen(cmd, shell=True, bufsize=-1,
+                             close_fds=util.closefds,
+                             stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                             universal_newlines=True, env=env)
+        stdout, stderr = p.communicate()
+        stderr = stderr.strip()
+        if stderr:
+            raise util.Abort(stderr)
+        return stdout
 
     def _wcrev(self):
         output = self._svncommand(['info', '--xml'])
@@ -549,7 +553,23 @@
                             'it has changes.\n' % self._path))
             return
         self._ui.note(_('removing subrepo %s\n') % self._path)
-        shutil.rmtree(self._ctx._repo.wjoin(self._path))
+
+        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)
+
+        path = self._ctx._repo.wjoin(self._path)
+        shutil.rmtree(path, onerror=onerror)
+        try:
+            os.removedirs(os.path.dirname(path))
+        except OSError:
+            pass
 
     def get(self, state):
         status = self._svncommand(['checkout', state[0], '--revision', state[1]])