diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py index 8b167ee8242fd7117185150a0015a753019f145e_bWVyY3VyaWFsL3N1YnJlcG8ucHk=..9efc316a67160831684bea85101616d971ed06b4_bWVyY3VyaWFsL3N1YnJlcG8ucHk= 100644 --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -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]]) diff --git a/tests/test-subrepo-svn.t b/tests/test-subrepo-svn.t index 8b167ee8242fd7117185150a0015a753019f145e_dGVzdHMvdGVzdC1zdWJyZXBvLXN2bi50..9efc316a67160831684bea85101616d971ed06b4_dGVzdHMvdGVzdC1zdWJyZXBvLXN2bi50 100644 --- a/tests/test-subrepo-svn.t +++ b/tests/test-subrepo-svn.t @@ -63,5 +63,6 @@ add first svn sub with leading whitespaces - $ echo "s = [svn] $SVNREPO/src" >> .hgsub + $ echo "s = [svn] $SVNREPO/src" >> .hgsub + $ echo "subdir/s = [svn] $SVNREPO/src" >> .hgsub $ svn co --quiet "$SVNREPO"/src s @@ -67,4 +68,6 @@ $ svn co --quiet "$SVNREPO"/src s + $ mkdir subdir + $ svn co --quiet "$SVNREPO"/src subdir/s $ hg add .hgsub $ hg ci -m1 committing subrepository s @@ -68,6 +71,7 @@ $ hg add .hgsub $ hg ci -m1 committing subrepository s + committing subrepository subdir/s make sure we avoid empty commits (issue2445) @@ -87,6 +91,9 @@ path s source file://*/svn-repo/src (glob) revision 2 + path subdir/s + source file://*/svn-repo/src (glob) + revision 2 change file in svn and hg, commit @@ -112,6 +119,9 @@ path s source file://*/svn-repo/src (glob) revision 3 + path subdir/s + source file://*/svn-repo/src (glob) + revision 2 $ echo a > s/a @@ -170,6 +180,6 @@ $ hg diff --subrepos -r 1:2 | grep -v diff --- a/.hgsubstate Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgsubstate Thu Jan 01 00:00:00 1970 +0000 - @@ -1,1 +1,1 @@ + @@ -1,2 +1,2 @@ -2 s +3 s @@ -174,5 +184,6 @@ -2 s +3 s + 2 subdir/s --- a/a Thu Jan 01 00:00:00 1970 +0000 +++ b/a Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +1,2 @@ @@ -195,6 +206,14 @@ $ cd .. $ hg clone t tc | fix_path updating to branch default + A tc/subdir/s/alpha + U tc/subdir/s + + Fetching external item into 'tc/subdir/s/externals' + A tc/subdir/s/externals/other + Checked out external at revision 1. + + Checked out revision 2. A tc/s/alpha U tc/s @@ -212,6 +231,9 @@ path s source file://*/svn-repo/src (glob) revision 3 + path subdir/s + source file://*/svn-repo/src (glob) + revision 2 verify subrepo is contained within the repo directory @@ -222,3 +244,4 @@ $ hg up null 0 files updated, 0 files merged, 3 files removed, 0 files unresolved + $ ls