diff -r 88cb01c4575e -r 0ae98cd2a83f mercurial/subrepo.py --- a/mercurial/subrepo.py Fri Jun 17 15:21:02 2011 -0500 +++ b/mercurial/subrepo.py Fri Jun 17 15:22:50 2011 -0500 @@ -526,7 +526,7 @@ self._ctx = ctx self._ui = ctx._repo.ui - def _svncommand(self, commands, filename=''): + def _svncommand(self, commands, filename='', failok=False): cmd = ['svn'] extrakw = {} if not self._ui.interactive(): @@ -551,15 +551,16 @@ universal_newlines=True, env=env, **extrakw) stdout, stderr = p.communicate() stderr = stderr.strip() - if p.returncode: - raise util.Abort(stderr or 'exited with code %d' % p.returncode) - if stderr: - self._ui.warn(stderr + '\n') - return stdout + if not failok: + if p.returncode: + raise util.Abort(stderr or 'exited with code %d' % p.returncode) + if stderr: + self._ui.warn(stderr + '\n') + return stdout, stderr @propertycache def _svnversion(self): - output = self._svncommand(['--version'], filename=None) + output, err = self._svncommand(['--version'], filename=None) m = re.search(r'^svn,\s+version\s+(\d+)\.(\d+)', output) if not m: raise util.Abort(_('cannot retrieve svn tool version')) @@ -569,7 +570,7 @@ # Get the working directory revision as well as the last # commit revision so we can compare the subrepo state with # both. We used to store the working directory one. - output = self._svncommand(['info', '--xml']) + output, err = self._svncommand(['info', '--xml']) doc = xml.dom.minidom.parseString(output) entries = doc.getElementsByTagName('entry') lastrev, rev = '0', '0' @@ -588,7 +589,7 @@ if the working directory was changed, and extchanges is True if any of these changes concern an external entry. """ - output = self._svncommand(['status', '--xml']) + output, err = self._svncommand(['status', '--xml']) externals, changes = [], [] doc = xml.dom.minidom.parseString(output) for e in doc.getElementsByTagName('entry'): @@ -623,13 +624,13 @@ if extchanged: # Do not try to commit externals raise util.Abort(_('cannot commit svn externals')) - commitinfo = self._svncommand(['commit', '-m', text]) + commitinfo, err = self._svncommand(['commit', '-m', text]) self._ui.status(commitinfo) newrev = re.search('Committed revision ([0-9]+).', commitinfo) if not newrev: raise util.Abort(commitinfo.splitlines()[-1]) newrev = newrev.groups()[0] - self._ui.status(self._svncommand(['update', '-r', newrev])) + self._ui.status(self._svncommand(['update', '-r', newrev])[0]) return newrev def remove(self): @@ -663,9 +664,15 @@ if self._svnversion >= (1, 5): args.append('--force') args.extend([state[0], '--revision', state[1]]) - status = self._svncommand(args) + status, err = self._svncommand(args, failok=True) if not re.search('Checked out revision [0-9]+.', status): - raise util.Abort(status.splitlines()[-1]) + if ('is already a working copy for a different URL' in err + and (self._wcchanged() == (False, False))): + # obstructed but clean working copy, so just blow it away. + self.remove() + self.get(state, overwrite=False) + return + raise util.Abort((status or err).splitlines()[-1]) self._ui.status(status) def merge(self, state):