Show More
@@ -526,7 +526,7 b' class svnsubrepo(abstractsubrepo):' | |||
|
526 | 526 | self._ctx = ctx |
|
527 | 527 | self._ui = ctx._repo.ui |
|
528 | 528 | |
|
529 | def _svncommand(self, commands, filename=''): | |
|
529 | def _svncommand(self, commands, filename='', failok=False): | |
|
530 | 530 | cmd = ['svn'] |
|
531 | 531 | extrakw = {} |
|
532 | 532 | if not self._ui.interactive(): |
@@ -551,15 +551,16 b' class svnsubrepo(abstractsubrepo):' | |||
|
551 | 551 | universal_newlines=True, env=env, **extrakw) |
|
552 | 552 | stdout, stderr = p.communicate() |
|
553 | 553 | stderr = stderr.strip() |
|
554 |
if |
|
|
555 | raise util.Abort(stderr or 'exited with code %d' % p.returncode) | |
|
556 | if stderr: | |
|
557 |
|
|
|
558 | return stdout | |
|
554 | if not failok: | |
|
555 | if p.returncode: | |
|
556 | raise util.Abort(stderr or 'exited with code %d' % p.returncode) | |
|
557 | if stderr: | |
|
558 | self._ui.warn(stderr + '\n') | |
|
559 | return stdout, stderr | |
|
559 | 560 | |
|
560 | 561 | @propertycache |
|
561 | 562 | def _svnversion(self): |
|
562 | output = self._svncommand(['--version'], filename=None) | |
|
563 | output, err = self._svncommand(['--version'], filename=None) | |
|
563 | 564 | m = re.search(r'^svn,\s+version\s+(\d+)\.(\d+)', output) |
|
564 | 565 | if not m: |
|
565 | 566 | raise util.Abort(_('cannot retrieve svn tool version')) |
@@ -569,7 +570,7 b' class svnsubrepo(abstractsubrepo):' | |||
|
569 | 570 | # Get the working directory revision as well as the last |
|
570 | 571 | # commit revision so we can compare the subrepo state with |
|
571 | 572 | # both. We used to store the working directory one. |
|
572 | output = self._svncommand(['info', '--xml']) | |
|
573 | output, err = self._svncommand(['info', '--xml']) | |
|
573 | 574 | doc = xml.dom.minidom.parseString(output) |
|
574 | 575 | entries = doc.getElementsByTagName('entry') |
|
575 | 576 | lastrev, rev = '0', '0' |
@@ -588,7 +589,7 b' class svnsubrepo(abstractsubrepo):' | |||
|
588 | 589 | if the working directory was changed, and extchanges is |
|
589 | 590 | True if any of these changes concern an external entry. |
|
590 | 591 | """ |
|
591 | output = self._svncommand(['status', '--xml']) | |
|
592 | output, err = self._svncommand(['status', '--xml']) | |
|
592 | 593 | externals, changes = [], [] |
|
593 | 594 | doc = xml.dom.minidom.parseString(output) |
|
594 | 595 | for e in doc.getElementsByTagName('entry'): |
@@ -623,13 +624,13 b' class svnsubrepo(abstractsubrepo):' | |||
|
623 | 624 | if extchanged: |
|
624 | 625 | # Do not try to commit externals |
|
625 | 626 | raise util.Abort(_('cannot commit svn externals')) |
|
626 | commitinfo = self._svncommand(['commit', '-m', text]) | |
|
627 | commitinfo, err = self._svncommand(['commit', '-m', text]) | |
|
627 | 628 | self._ui.status(commitinfo) |
|
628 | 629 | newrev = re.search('Committed revision ([0-9]+).', commitinfo) |
|
629 | 630 | if not newrev: |
|
630 | 631 | raise util.Abort(commitinfo.splitlines()[-1]) |
|
631 | 632 | newrev = newrev.groups()[0] |
|
632 | self._ui.status(self._svncommand(['update', '-r', newrev])) | |
|
633 | self._ui.status(self._svncommand(['update', '-r', newrev])[0]) | |
|
633 | 634 | return newrev |
|
634 | 635 | |
|
635 | 636 | def remove(self): |
@@ -663,9 +664,15 b' class svnsubrepo(abstractsubrepo):' | |||
|
663 | 664 | if self._svnversion >= (1, 5): |
|
664 | 665 | args.append('--force') |
|
665 | 666 | args.extend([state[0], '--revision', state[1]]) |
|
666 | status = self._svncommand(args) | |
|
667 | status, err = self._svncommand(args, failok=True) | |
|
667 | 668 | if not re.search('Checked out revision [0-9]+.', status): |
|
668 | raise util.Abort(status.splitlines()[-1]) | |
|
669 | if ('is already a working copy for a different URL' in err | |
|
670 | and (self._wcchanged() == (False, False))): | |
|
671 | # obstructed but clean working copy, so just blow it away. | |
|
672 | self.remove() | |
|
673 | self.get(state, overwrite=False) | |
|
674 | return | |
|
675 | raise util.Abort((status or err).splitlines()[-1]) | |
|
669 | 676 | self._ui.status(status) |
|
670 | 677 | |
|
671 | 678 | def merge(self, state): |
@@ -489,3 +489,33 b' are unknown directories being replaced b' | |||
|
489 | 489 | $ if "$TESTDIR/hghave" -q svn15; then |
|
490 | 490 | > hg up 2 >/dev/null 2>&1 || echo update failed |
|
491 | 491 | > fi |
|
492 | ||
|
493 | Modify one of the externals to point to a different path so we can | |
|
494 | test having obstructions when switching branches on checkout: | |
|
495 | $ hg checkout tip | |
|
496 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
497 | $ echo "obstruct = [svn] $SVNREPO/externals" >> .hgsub | |
|
498 | $ svn co -r5 --quiet "$SVNREPO"/externals obstruct | |
|
499 | $ hg commit -m 'Start making obstructed wc' | |
|
500 | committing subrepository obstruct | |
|
501 | $ hg book other | |
|
502 | $ hg co -r 'p1(tip)' | |
|
503 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
504 | $ echo "obstruct = [svn] $SVNREPO/src" >> .hgsub | |
|
505 | $ svn co -r5 --quiet "$SVNREPO"/src obstruct | |
|
506 | $ hg commit -m 'Other branch which will be obstructed' | |
|
507 | committing subrepository obstruct | |
|
508 | created new head | |
|
509 | ||
|
510 | Switching back to the head where we have another path mapped to the | |
|
511 | same subrepo should work if the subrepo is clean. | |
|
512 | $ hg co other | |
|
513 | A $TESTTMP/rebaserepo/obstruct/other | |
|
514 | Checked out revision 1. | |
|
515 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
|
516 | ||
|
517 | This is surprising, but is also correct based on the current code: | |
|
518 | $ echo "updating should (maybe) fail" > obstruct/other | |
|
519 | $ hg co tip | |
|
520 | abort: crosses branches (merge branches or use --clean to discard changes) | |
|
521 | [255] |
General Comments 0
You need to be logged in to leave comments.
Login now