convert: fix svn branch source detection corner case
It was confused by composite-looking revisions made by copy + remove.
--- 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: