# HG changeset patch # User Patrick Mezard # Date 1208205094 -7200 # Node ID a7492fb2107b9c3ba8fc865af8915e9989dca4e0 # Parent 3447c088a516836e6bd171b6052dbd219af9d86f convert: fix svn branch source detection corner case It was confused by composite-looking revisions made by copy + remove. diff -r 3447c088a516 -r a7492fb2107b hgext/convert/subversion.py --- 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: diff -r 3447c088a516 -r a7492fb2107b tests/test-convert-svn-branches.out --- 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: