498 try: |
498 try: |
499 tagid = self.latest(source, sourcerev) |
499 tagid = self.latest(source, sourcerev) |
500 if tagid and tagname not in tags: |
500 if tagid and tagname not in tags: |
501 tags[tagname] = tagid |
501 tags[tagname] = tagid |
502 except SvnPathNotFound: |
502 except SvnPathNotFound: |
503 # It happens when we are following directories we assumed |
503 # It happens when we are following directories |
504 # were copied with their parents but were really created |
504 # we assumed were copied with their parents |
505 # in the tag directory. |
505 # but were really created in the tag |
|
506 # directory. |
506 pass |
507 pass |
507 pendings = remainings |
508 pendings = remainings |
508 tagspath = srctagspath |
509 tagspath = srctagspath |
509 |
510 |
510 except SubversionException: |
511 except SubversionException: |
561 except SubversionException: |
562 except SubversionException: |
562 dirent = None |
563 dirent = None |
563 if not dirent: |
564 if not dirent: |
564 raise SvnPathNotFound(_('%s not found up to revision %d') % (path, stop)) |
565 raise SvnPathNotFound(_('%s not found up to revision %d') % (path, stop)) |
565 |
566 |
566 # stat() gives us the previous revision on this line of development, but |
567 # stat() gives us the previous revision on this line of |
567 # it might be in *another module*. Fetch the log and detect renames down |
568 # development, but it might be in *another module*. Fetch the |
568 # to the latest revision. |
569 # log and detect renames down to the latest revision. |
569 stream = self._getlog([path], stop, dirent.created_rev) |
570 stream = self._getlog([path], stop, dirent.created_rev) |
570 try: |
571 try: |
571 for entry in stream: |
572 for entry in stream: |
572 paths, revnum, author, date, message = entry |
573 paths, revnum, author, date, message = entry |
573 if revnum <= dirent.created_rev: |
574 if revnum <= dirent.created_rev: |
621 self.prevmodule = module |
622 self.prevmodule = module |
622 return prevmodule |
623 return prevmodule |
623 |
624 |
624 def expandpaths(self, rev, paths, parents): |
625 def expandpaths(self, rev, paths, parents): |
625 entries = [] |
626 entries = [] |
626 copyfrom = {} # Map of entrypath, revision for finding source of deleted revisions. |
627 # Map of entrypath, revision for finding source of deleted |
|
628 # revisions. |
|
629 copyfrom = {} |
627 copies = {} |
630 copies = {} |
628 |
631 |
629 new_module, revnum = self.revsplit(rev)[1:] |
632 new_module, revnum = self.revsplit(rev)[1:] |
630 if new_module != self.module: |
633 if new_module != self.module: |
631 self.module = new_module |
634 self.module = new_module |
638 kind = self._checkpath(entrypath, revnum) |
641 kind = self._checkpath(entrypath, revnum) |
639 if kind == svn.core.svn_node_file: |
642 if kind == svn.core.svn_node_file: |
640 entries.append(self.recode(entry)) |
643 entries.append(self.recode(entry)) |
641 if not ent.copyfrom_path or not parents: |
644 if not ent.copyfrom_path or not parents: |
642 continue |
645 continue |
643 # Copy sources not in parent revisions cannot be represented, |
646 # Copy sources not in parent revisions cannot be |
644 # ignore their origin for now |
647 # represented, ignore their origin for now |
645 pmodule, prevnum = self.revsplit(parents[0])[1:] |
648 pmodule, prevnum = self.revsplit(parents[0])[1:] |
646 if ent.copyfrom_rev < prevnum: |
649 if ent.copyfrom_rev < prevnum: |
647 continue |
650 continue |
648 copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule) |
651 copyfrom_path = self.getrelpath(ent.copyfrom_path, pmodule) |
649 if not copyfrom_path: |
652 if not copyfrom_path: |
652 (entrypath, copyfrom_path, ent.copyfrom_rev)) |
655 (entrypath, copyfrom_path, ent.copyfrom_rev)) |
653 copies[self.recode(entry)] = self.recode(copyfrom_path) |
656 copies[self.recode(entry)] = self.recode(copyfrom_path) |
654 elif kind == 0: # gone, but had better be a deleted *file* |
657 elif kind == 0: # gone, but had better be a deleted *file* |
655 self.ui.debug(_("gone from %s\n") % ent.copyfrom_rev) |
658 self.ui.debug(_("gone from %s\n") % ent.copyfrom_rev) |
656 |
659 |
657 # if a branch is created but entries are removed in the same |
660 # if a branch is created but entries are removed in |
658 # changeset, get the right fromrev |
661 # the same changeset, get the right fromrev |
659 # parents cannot be empty here, you cannot remove things from |
662 # parents cannot be empty here, you cannot remove |
660 # a root revision. |
663 # things from a root revision. |
661 uuid, old_module, fromrev = self.revsplit(parents[0]) |
664 uuid, old_module, fromrev = self.revsplit(parents[0]) |
662 |
665 |
663 basepath = old_module + "/" + self.getrelpath(path) |
666 basepath = old_module + "/" + self.getrelpath(path) |
664 entrypath = basepath |
667 entrypath = basepath |
665 |
668 |
676 |
679 |
677 self.ui.debug(_("base, entry %s %s\n") % (basepath, entrypath)) |
680 self.ui.debug(_("base, entry %s %s\n") % (basepath, entrypath)) |
678 |
681 |
679 frompath, froment = lookup_parts(entrypath) or (None, revnum - 1) |
682 frompath, froment = lookup_parts(entrypath) or (None, revnum - 1) |
680 |
683 |
681 # need to remove fragment from lookup_parts and replace with copyfrom_path |
684 # need to remove fragment from lookup_parts and |
|
685 # replace with copyfrom_path |
682 if frompath is not None: |
686 if frompath is not None: |
683 self.ui.debug(_("munge-o-matic\n")) |
687 self.ui.debug(_("munge-o-matic\n")) |
684 self.ui.debug(entrypath + '\n') |
688 self.ui.debug(entrypath + '\n') |
685 self.ui.debug(entrypath[len(frompath):] + '\n') |
689 self.ui.debug(entrypath[len(frompath):] + '\n') |
686 entrypath = froment.copyfrom_path + entrypath[len(frompath):] |
690 entrypath = froment.copyfrom_path + entrypath[len(frompath):] |
687 fromrev = froment.copyfrom_rev |
691 fromrev = froment.copyfrom_rev |
688 self.ui.debug(_("info: %s %s %s %s\n") % (frompath, froment, ent, entrypath)) |
692 self.ui.debug(_("info: %s %s %s %s\n") % (frompath, froment, ent, entrypath)) |
689 |
693 |
690 # We can avoid the reparent calls if the module has not changed |
694 # We can avoid the reparent calls if the module has |
691 # but it probably does not worth the pain. |
695 # not changed but it probably does not worth the pain. |
692 prevmodule = self.reparent('') |
696 prevmodule = self.reparent('') |
693 fromkind = svn.ra.check_path(self.ra, entrypath.strip('/'), fromrev) |
697 fromkind = svn.ra.check_path(self.ra, entrypath.strip('/'), fromrev) |
694 self.reparent(prevmodule) |
698 self.reparent(prevmodule) |
695 |
699 |
696 if fromkind == svn.core.svn_node_file: # a deleted file |
700 if fromkind == svn.core.svn_node_file: # a deleted file |
697 entries.append(self.recode(entry)) |
701 entries.append(self.recode(entry)) |
698 elif fromkind == svn.core.svn_node_dir: |
702 elif fromkind == svn.core.svn_node_dir: |
699 # print "Deleted/moved non-file:", revnum, path, ent |
703 # print "Deleted/moved non-file:", revnum, path, ent |
700 # children = self._find_children(path, revnum - 1) |
704 # children = self._find_children(path, revnum - 1) |
701 # print "find children %s@%d from %d action %s" % (path, revnum, ent.copyfrom_rev, ent.action) |
705 # print ("find children %s@%d from %d action %s" % |
|
706 # (path, revnum, ent.copyfrom_rev, ent.action)) |
702 # Sometimes this is tricky. For example: in |
707 # Sometimes this is tricky. For example: in |
703 # The Subversion Repository revision 6940 a dir |
708 # The Subversion Repository revision 6940 a dir |
704 # was copied and one of its files was deleted |
709 # was copied and one of its files was deleted |
705 # from the new location in the same commit. This |
710 # from the new location in the same commit. This |
706 # code can't deal with that yet. |
711 # code can't deal with that yet. |
737 if ent.action == 'M': |
742 if ent.action == 'M': |
738 continue |
743 continue |
739 |
744 |
740 # Also this could create duplicate entries. Not sure |
745 # Also this could create duplicate entries. Not sure |
741 # whether this will matter. Maybe should make entries a set. |
746 # whether this will matter. Maybe should make entries a set. |
742 # print "Changed directory", revnum, path, ent.action, ent.copyfrom_path, ent.copyfrom_rev |
747 # print "Changed directory", revnum, path, ent.action, \ |
|
748 # ent.copyfrom_path, ent.copyfrom_rev |
743 # This will fail if a directory was copied |
749 # This will fail if a directory was copied |
744 # from another branch and then some of its files |
750 # from another branch and then some of its files |
745 # were deleted in the same transaction. |
751 # were deleted in the same transaction. |
746 children = sorted(self._find_children(path, revnum)) |
752 children = sorted(self._find_children(path, revnum)) |
747 for child in children: |
753 for child in children: |
755 # Need to filter out directories here... |
761 # Need to filter out directories here... |
756 kind = self._checkpath(entrypath, revnum) |
762 kind = self._checkpath(entrypath, revnum) |
757 if kind != svn.core.svn_node_dir: |
763 if kind != svn.core.svn_node_dir: |
758 entries.append(self.recode(entrypath)) |
764 entries.append(self.recode(entrypath)) |
759 |
765 |
760 # Copies here (must copy all from source) |
766 # Copies here (must copy all from source) Probably not |
761 # Probably not a real problem for us if |
767 # a real problem for us if source does not exist |
762 # source does not exist |
|
763 if not ent.copyfrom_path or not parents: |
768 if not ent.copyfrom_path or not parents: |
764 continue |
769 continue |
765 # Copy sources not in parent revisions cannot be represented, |
770 # Copy sources not in parent revisions cannot be |
766 # ignore their origin for now |
771 # represented, ignore their origin for now |
767 pmodule, prevnum = self.revsplit(parents[0])[1:] |
772 pmodule, prevnum = self.revsplit(parents[0])[1:] |
768 if ent.copyfrom_rev < prevnum: |
773 if ent.copyfrom_rev < prevnum: |
769 continue |
774 continue |
770 copyfrompath = ent.copyfrom_path.decode(self.encoding) |
775 copyfrompath = ent.copyfrom_path.decode(self.encoding) |
771 copyfrompath = self.getrelpath(copyfrompath, pmodule) |
776 copyfrompath = self.getrelpath(copyfrompath, pmodule) |