changeset 6545:a7492fb2107b

convert: fix svn branch source detection corner case It was confused by composite-looking revisions made by copy + remove.
author Patrick Mezard <pmezard@gmail.com>
date Mon, 14 Apr 2008 22:31:34 +0200
parents 3447c088a516
children 075b2c9aed37
files hgext/convert/subversion.py tests/test-convert-svn-branches.out
diffstat 2 files changed, 21 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/convert/subversion.py	Mon Apr 14 22:31:34 2008 +0200
+++ b/hgext/convert/subversion.py	Mon Apr 14 22:31:34 2008 +0200
@@ -709,6 +709,13 @@
             from_revnum, to_revnum = to_revnum, from_revnum
 
         self.child_cset = None
+
+        def isdescendantof(parent, child):
+            if not child or not parent or not child.startswith(parent):
+                return False
+            subpath = child[len(parent):]
+            return len(subpath) > 1 and subpath[0] == '/'
+
         def parselogentry(orig_paths, revnum, author, date, message):
             """Return the parsed commit object or None, and True if
             the revision is a branch root.
@@ -732,10 +739,21 @@
             if root_paths:
                 path, ent = root_paths[-1]
                 if ent.copyfrom_path:
+                    # If dir was moved while one of its file was removed 
+                    # the log may look like:
+                    # A /dir   (from /dir:x)
+                    # A /dir/a (from /dir/a:y)
+                    # A /dir/b (from /dir/b:z)
+                    # ...
+                    # for all remaining children.
+                    # Let's take the highest child element from rev as source.
+                    copies = [(p,e) for p,e in orig_paths[:-1] 
+                          if isdescendantof(ent.copyfrom_path, e.copyfrom_path)]
+                    fromrev = max([e.copyfrom_rev for p,e in copies] + [ent.copyfrom_rev])
                     branched = True
                     newpath = ent.copyfrom_path + self.module[len(path):]
                     # ent.copyfrom_rev may not be the actual last revision
-                    previd = self.latest(newpath, ent.copyfrom_rev)
+                    previd = self.latest(newpath, fromrev)
                     if previd is not None:
                         prevmodule, prevnum = self.revsplit(previd)[1:]
                         if prevnum >= self.startrev:
--- a/tests/test-convert-svn-branches.out	Mon Apr 14 22:31:34 2008 +0200
+++ b/tests/test-convert-svn-branches.out	Mon Apr 14 22:31:34 2008 +0200
@@ -117,8 +117,8 @@
 | | |
 | o |  branch= 3 change a files: a
 | | |
-+---o  branch=old 2 branch trunk, remove c files: a b
-| |
+| | o  branch=old 2 branch trunk, remove c files:
+| |/
 | o  branch= 1 hello files: a b c
 |/
 o  branch= 0 init projA files: