convert: handle past or foreign partial svn copies
authorPatrick Mezard <pmezard@gmail.com>
Mon, 14 Apr 2008 22:31:34 +0200
changeset 6543 a6e2e60b34d0
parent 6542 e7810e61f7c1
child 6544 3447c088a516
convert: handle past or foreign partial svn copies Subversion allows revisions to be composed of subparts coming from revisions before the parent or from other part of the repository. There is no simple representation for these now, keep the changes but do not track their origins.
hgext/convert/subversion.py
tests/test-convert-svn-move
tests/test-convert-svn-move.out
--- a/hgext/convert/subversion.py	Mon Apr 14 22:31:33 2008 +0200
+++ b/hgext/convert/subversion.py	Mon Apr 14 22:31:34 2008 +0200
@@ -675,28 +675,30 @@
                 # Copies here (must copy all from source)
                 # Probably not a real problem for us if
                 # source does not exist
-                if not ent.copyfrom_path:
+                if not ent.copyfrom_path or not parents:
                     continue
-                copyfrompath = self.getrelpath(ent.copyfrom_path.decode(self.encoding))
+                # Copy sources not in parent revisions cannot be represented,
+                # ignore their origin for now
+                pmodule, prevnum = self.revsplit(parents[0])[1:]
+                if ent.copyfrom_rev < prevnum:
+                    continue
+                copyfrompath = ent.copyfrom_path.decode(self.encoding)
+                copyfrompath = self.getrelpath(copyfrompath, pmodule)
                 if not copyfrompath:
                     continue
                 copyfrom[path] = ent
                 self.ui.debug("mark %s came from %s:%d\n" 
                               % (path, copyfrompath, ent.copyfrom_rev))
-
-                # Good, /probably/ a regular copy. Really should check
-                # to see whether the parent revision actually contains
-                # the directory in question.
                 children = self._find_children(ent.copyfrom_path, ent.copyfrom_rev)
                 children.sort()
                 for child in children:
-                    entrypath = self.getrelpath("/" + child)
+                    entrypath = self.getrelpath("/" + child, pmodule)
                     if not entrypath:
                         continue
                     entry = entrypath.decode(self.encoding)
                     copytopath = path + entry[len(copyfrompath):]
                     copytopath = self.getrelpath(copytopath)
-                    copies[self.recode(copytopath)] = self.recode(entry)
+                    copies[self.recode(copytopath)] = self.recode(entry, pmodule)
 
         return (util.unique(entries), copies)
 
--- a/tests/test-convert-svn-move	Mon Apr 14 22:31:33 2008 +0200
+++ b/tests/test-convert-svn-move	Mon Apr 14 22:31:34 2008 +0200
@@ -27,8 +27,10 @@
 mkdir trunk
 echo a > trunk/a
 mkdir trunk/d1
+mkdir trunk/d2
 echo b > trunk/d1/b
 echo c > trunk/d1/c
+echo d > trunk/d2/d
 cd ..
 
 svnurl=file://$svnpath/svn-repo/projA
@@ -50,10 +52,14 @@
 svn add subproject/branches
 svn ci -m createbranches
 svn mv $svnurl/subproject/d1 $svnurl/subproject/trunk/d1 -m moved1
+svn mv $svnurl/subproject/d2 $svnurl/subproject/trunk/d2 -m moved2
 svn up
 "$TESTDIR/svn-safe-append.py" b subproject/trunk/d1/b
-svn ci -m changeb
+svn rm subproject/trunk/d2
+svn ci -m "changeb and rm d2"
 svn mv $svnurl/subproject/trunk/d1 $svnurl/subproject/branches/d1 -m moved1again
+echo % copy a directory from a past revision
+svn copy -r 7 $svnurl/subproject/trunk/d2 $svnurl/subproject/trunk -m copydirfrompast
 cd ..
 
 echo % convert trunk and branches
--- a/tests/test-convert-svn-move.out	Mon Apr 14 22:31:33 2008 +0200
+++ b/tests/test-convert-svn-move.out	Mon Apr 14 22:31:34 2008 +0200
@@ -4,6 +4,8 @@
 Adding         projA/trunk/d1
 Adding         projA/trunk/d1/b
 Adding         projA/trunk/d1/c
+Adding         projA/trunk/d2
+Adding         projA/trunk/d2/d
 
 Committed revision 1.
 % update svn repository
@@ -12,6 +14,8 @@
 A    A/trunk/d1
 A    A/trunk/d1/b
 A    A/trunk/d1/c
+A    A/trunk/d2
+A    A/trunk/d2/d
 Checked out revision 1.
 Sending        trunk/a
 Sending        trunk/d1/c
@@ -25,6 +29,8 @@
 A    subproject/d1
 A    subproject/d1/b
 A    subproject/d1/c
+A    subproject/d2
+A    subproject/d2/d
 Updated to revision 3.
 A         subproject/trunk
 Adding         subproject/trunk
@@ -36,35 +42,52 @@
 Committed revision 5.
 
 Committed revision 6.
+
+Committed revision 7.
 A    subproject/trunk/d1
 A    subproject/trunk/d1/b
 A    subproject/trunk/d1/c
+A    subproject/trunk/d2
+A    subproject/trunk/d2/d
 D    subproject/d1
-Updated to revision 6.
+D    subproject/d2
+Updated to revision 7.
+D         subproject/trunk/d2/d
+D         subproject/trunk/d2
 Sending        subproject/trunk/d1/b
+Deleting       subproject/trunk/d2
 Transmitting file data .
-Committed revision 7.
+Committed revision 8.
 
-Committed revision 8.
+Committed revision 9.
+% copy a directory from a past revision
+
+Committed revision 10.
 % convert trunk and branches
 initializing destination A-hg repository
 scanning source...
 sorting...
 converting...
-6 createtrunk
-5 moved1
-4 moved1
-3 changeb
-2 changeb
+8 createtrunk
+7 moved1
+6 moved1
+5 moved2
+4 changeb and rm d2
+3 changeb and rm d2
+2 moved1again
 1 moved1again
-0 moved1again
-o  6 moved1again files: d1/b d1/c
+0 copydirfrompast
+o  8 copydirfrompast files: d2/d
+|
+o  7 moved1again files: d1/b d1/c
 |
-| o  5 moved1again files:
+| o  6 moved1again files:
+| |
+o |  5 changeb and rm d2 files: d1/b d2/d
 | |
-o |  4 changeb files: d1/b
+| o  4 changeb and rm d2 files: b
 | |
-| o  3 changeb files: b
+o |  3 moved2 files: d2/d
 | |
 o |  2 moved1 files: d1/b d1/c
 | |
@@ -72,5 +95,5 @@
 |
 o  0 createtrunk files:
 
-default                        6:
-d1                             5:
+default                        8:
+d1                             6: