Mercurial > hg-stable
comparison hgext/convert/subversion.py @ 13690:af331f557942
convert/svn: extract revsplit() in a function
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Thu, 17 Mar 2011 22:17:27 +0100 |
parents | 30a0e3519f69 |
children | d13913355390 |
comparison
equal
deleted
inserted
replaced
13689:65399579da68 | 13690:af331f557942 |
---|---|
38 except ImportError: | 38 except ImportError: |
39 svn = None | 39 svn = None |
40 | 40 |
41 class SvnPathNotFound(Exception): | 41 class SvnPathNotFound(Exception): |
42 pass | 42 pass |
43 | |
44 def revsplit(rev): | |
45 """Parse a revision string and return (uuid, path, revnum).""" | |
46 url, revnum = rev.rsplit('@', 1) | |
47 parts = url.split('/', 1) | |
48 mod = '' | |
49 if len(parts) > 1: | |
50 mod = '/' + parts[1] | |
51 return parts[0][4:], mod, int(revnum) | |
43 | 52 |
44 def geturl(path): | 53 def geturl(path): |
45 try: | 54 try: |
46 return svn.client.url_from_path(svn.core.svn_path_canonicalize(path)) | 55 return svn.client.url_from_path(svn.core.svn_path_canonicalize(path)) |
47 except SubversionException: | 56 except SubversionException: |
284 self.convertfp = None | 293 self.convertfp = None |
285 | 294 |
286 def setrevmap(self, revmap): | 295 def setrevmap(self, revmap): |
287 lastrevs = {} | 296 lastrevs = {} |
288 for revid in revmap.iterkeys(): | 297 for revid in revmap.iterkeys(): |
289 uuid, module, revnum = self.revsplit(revid) | 298 uuid, module, revnum = revsplit(revid) |
290 lastrevnum = lastrevs.setdefault(module, revnum) | 299 lastrevnum = lastrevs.setdefault(module, revnum) |
291 if revnum > lastrevnum: | 300 if revnum > lastrevnum: |
292 lastrevs[module] = revnum | 301 lastrevs[module] = revnum |
293 self.lastrevs = lastrevs | 302 self.lastrevs = lastrevs |
294 | 303 |
379 (paths, parents) = self.paths[rev] | 388 (paths, parents) = self.paths[rev] |
380 if parents: | 389 if parents: |
381 files, self.removed, copies = self.expandpaths(rev, paths, parents) | 390 files, self.removed, copies = self.expandpaths(rev, paths, parents) |
382 else: | 391 else: |
383 # Perform a full checkout on roots | 392 # Perform a full checkout on roots |
384 uuid, module, revnum = self.revsplit(rev) | 393 uuid, module, revnum = revsplit(rev) |
385 entries = svn.client.ls(self.baseurl + urllib.quote(module), | 394 entries = svn.client.ls(self.baseurl + urllib.quote(module), |
386 optrev(revnum), True, self.ctx) | 395 optrev(revnum), True, self.ctx) |
387 files = [n for n, e in entries.iteritems() | 396 files = [n for n, e in entries.iteritems() |
388 if e.kind == svn.core.svn_node_file] | 397 if e.kind == svn.core.svn_node_file] |
389 copies = {} | 398 copies = {} |
401 self._changescache = (rev, changes) | 410 self._changescache = (rev, changes) |
402 return [f[0] for f in changes[0]] | 411 return [f[0] for f in changes[0]] |
403 | 412 |
404 def getcommit(self, rev): | 413 def getcommit(self, rev): |
405 if rev not in self.commits: | 414 if rev not in self.commits: |
406 uuid, module, revnum = self.revsplit(rev) | 415 uuid, module, revnum = revsplit(rev) |
407 self.module = module | 416 self.module = module |
408 self.reparent(module) | 417 self.reparent(module) |
409 # We assume that: | 418 # We assume that: |
410 # - requests for revisions after "stop" come from the | 419 # - requests for revisions after "stop" come from the |
411 # revision graph backward traversal. Cache all of them | 420 # revision graph backward traversal. Cache all of them |
528 return 'svn:%s%s@%s' % (self.uuid, module or self.module, revnum) | 537 return 'svn:%s%s@%s' % (self.uuid, module or self.module, revnum) |
529 | 538 |
530 def revnum(self, rev): | 539 def revnum(self, rev): |
531 return int(rev.split('@')[-1]) | 540 return int(rev.split('@')[-1]) |
532 | 541 |
533 def revsplit(self, rev): | |
534 url, revnum = rev.rsplit('@', 1) | |
535 revnum = int(revnum) | |
536 parts = url.split('/', 1) | |
537 uuid = parts.pop(0)[4:] | |
538 mod = '' | |
539 if parts: | |
540 mod = '/' + parts[0] | |
541 return uuid, mod, revnum | |
542 | |
543 def latest(self, path, stop=0): | 542 def latest(self, path, stop=0): |
544 """Find the latest revid affecting path, up to stop. It may return | 543 """Find the latest revid affecting path, up to stop. It may return |
545 a revision in a different module, since a branch may be moved without | 544 a revision in a different module, since a branch may be moved without |
546 a change being reported. Return None if computed module does not | 545 a change being reported. Return None if computed module does not |
547 belong to rootmodule subtree. | 546 belong to rootmodule subtree. |
604 | 603 |
605 def expandpaths(self, rev, paths, parents): | 604 def expandpaths(self, rev, paths, parents): |
606 changed, removed = set(), set() | 605 changed, removed = set(), set() |
607 copies = {} | 606 copies = {} |
608 | 607 |
609 new_module, revnum = self.revsplit(rev)[1:] | 608 new_module, revnum = revsplit(rev)[1:] |
610 if new_module != self.module: | 609 if new_module != self.module: |
611 self.module = new_module | 610 self.module = new_module |
612 self.reparent(self.module) | 611 self.reparent(self.module) |
613 | 612 |
614 for i, (path, ent) in enumerate(paths): | 613 for i, (path, ent) in enumerate(paths): |
621 changed.add(self.recode(entrypath)) | 620 changed.add(self.recode(entrypath)) |
622 if not ent.copyfrom_path or not parents: | 621 if not ent.copyfrom_path or not parents: |
623 continue | 622 continue |
624 # Copy sources not in parent revisions cannot be | 623 # Copy sources not in parent revisions cannot be |
625 # represented, ignore their origin for now | 624 # represented, ignore their origin for now |
626 pmodule, prevnum = self.revsplit(parents[0])[1:] | 625 pmodule, prevnum = revsplit(parents[0])[1:] |
627 if ent.copyfrom_rev < prevnum: | 626 if ent.copyfrom_rev < prevnum: |
628 continue | 627 continue |
629 copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule) | 628 copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule) |
630 if not copyfrom_path: | 629 if not copyfrom_path: |
631 continue | 630 continue |
632 self.ui.debug("copied to %s from %s@%s\n" % | 631 self.ui.debug("copied to %s from %s@%s\n" % |
633 (entrypath, copyfrom_path, ent.copyfrom_rev)) | 632 (entrypath, copyfrom_path, ent.copyfrom_rev)) |
634 copies[self.recode(entrypath)] = self.recode(copyfrom_path) | 633 copies[self.recode(entrypath)] = self.recode(copyfrom_path) |
635 elif kind == 0: # gone, but had better be a deleted *file* | 634 elif kind == 0: # gone, but had better be a deleted *file* |
636 self.ui.debug("gone from %s\n" % ent.copyfrom_rev) | 635 self.ui.debug("gone from %s\n" % ent.copyfrom_rev) |
637 pmodule, prevnum = self.revsplit(parents[0])[1:] | 636 pmodule, prevnum = revsplit(parents[0])[1:] |
638 parentpath = pmodule + "/" + entrypath | 637 parentpath = pmodule + "/" + entrypath |
639 fromkind = self._checkpath(entrypath, prevnum, pmodule) | 638 fromkind = self._checkpath(entrypath, prevnum, pmodule) |
640 | 639 |
641 if fromkind == svn.core.svn_node_file: | 640 if fromkind == svn.core.svn_node_file: |
642 removed.add(self.recode(entrypath)) | 641 removed.add(self.recode(entrypath)) |
658 # then we shouldn't need to look for its children. | 657 # then we shouldn't need to look for its children. |
659 continue | 658 continue |
660 if ent.action == 'R' and parents: | 659 if ent.action == 'R' and parents: |
661 # If a directory is replacing a file, mark the previous | 660 # If a directory is replacing a file, mark the previous |
662 # file as deleted | 661 # file as deleted |
663 pmodule, prevnum = self.revsplit(parents[0])[1:] | 662 pmodule, prevnum = revsplit(parents[0])[1:] |
664 pkind = self._checkpath(entrypath, prevnum, pmodule) | 663 pkind = self._checkpath(entrypath, prevnum, pmodule) |
665 if pkind == svn.core.svn_node_file: | 664 if pkind == svn.core.svn_node_file: |
666 removed.add(self.recode(entrypath)) | 665 removed.add(self.recode(entrypath)) |
667 elif pkind == svn.core.svn_node_dir: | 666 elif pkind == svn.core.svn_node_dir: |
668 # We do not know what files were kept or removed, | 667 # We do not know what files were kept or removed, |
680 # Handle directory copies | 679 # Handle directory copies |
681 if not ent.copyfrom_path or not parents: | 680 if not ent.copyfrom_path or not parents: |
682 continue | 681 continue |
683 # Copy sources not in parent revisions cannot be | 682 # Copy sources not in parent revisions cannot be |
684 # represented, ignore their origin for now | 683 # represented, ignore their origin for now |
685 pmodule, prevnum = self.revsplit(parents[0])[1:] | 684 pmodule, prevnum = revsplit(parents[0])[1:] |
686 if ent.copyfrom_rev < prevnum: | 685 if ent.copyfrom_rev < prevnum: |
687 continue | 686 continue |
688 copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule) | 687 copyfrompath = self.getrelpath(ent.copyfrom_path, pmodule) |
689 if not copyfrompath: | 688 if not copyfrompath: |
690 continue | 689 continue |
735 branched = True | 734 branched = True |
736 newpath = ent.copyfrom_path + self.module[len(path):] | 735 newpath = ent.copyfrom_path + self.module[len(path):] |
737 # ent.copyfrom_rev may not be the actual last revision | 736 # ent.copyfrom_rev may not be the actual last revision |
738 previd = self.latest(newpath, ent.copyfrom_rev) | 737 previd = self.latest(newpath, ent.copyfrom_rev) |
739 if previd is not None: | 738 if previd is not None: |
740 prevmodule, prevnum = self.revsplit(previd)[1:] | 739 prevmodule, prevnum = revsplit(previd)[1:] |
741 if prevnum >= self.startrev: | 740 if prevnum >= self.startrev: |
742 parents = [previd] | 741 parents = [previd] |
743 self.ui.note( | 742 self.ui.note( |
744 _('found parent of branch %s at %d: %s\n') % | 743 _('found parent of branch %s at %d: %s\n') % |
745 (self.module, prevnum, prevmodule)) | 744 (self.module, prevnum, prevmodule)) |
832 # TODO: ra.get_file transmits the whole file instead of diffs. | 831 # TODO: ra.get_file transmits the whole file instead of diffs. |
833 if file in self.removed: | 832 if file in self.removed: |
834 raise IOError() | 833 raise IOError() |
835 mode = '' | 834 mode = '' |
836 try: | 835 try: |
837 new_module, revnum = self.revsplit(rev)[1:] | 836 new_module, revnum = revsplit(rev)[1:] |
838 if self.module != new_module: | 837 if self.module != new_module: |
839 self.module = new_module | 838 self.module = new_module |
840 self.reparent(self.module) | 839 self.reparent(self.module) |
841 io = StringIO() | 840 io = StringIO() |
842 info = svn.ra.get_file(self.ra, file, revnum, io) | 841 info = svn.ra.get_file(self.ra, file, revnum, io) |