hgext/convert/subversion.py
changeset 8660 b9ec04eb2aa3
parent 8339 f55869abb5c3
child 8693 68e0a55eee6e
equal deleted inserted replaced
8659:1a6d702e059d 8660:b9ec04eb2aa3
   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)