Hi,

In your converted repository did it end up with a "demos"
directory and "changes" file in the top level of the tip of
au.asn.ucc.matt.dropbear branch? That indicates that the
conversion didn't work correctly.

I ended up converting my repository with the attached patch
- there isn't too much rename history that I care about, so
it purely looks at manifests revision-by-revision.

The converted repository now lives at
https://secure.ucc.asn.au/hg/dropbear/

Thanks,
Matt

On Mon, Nov 21, 2011 at 09:01:03AM -0600, Augie Fackler wrote:
> I just got a chance to take a look at this, and the cut down repo you 
> provided converted without a hitch. Should I try it on the full-size 
> repository? I don't see any obviously related changesets in hgext.convert's 
> recent history.
> 
> 
> On Sep 11, 2011, at 8:48 AM, Matt Johnston wrote:
> 
> > On Sat, Sep 10, 2011 at 10:07:49PM -0500, Augie Fackler wrote:
> >>> Have you tried http://mercurial.selenic.com/wiki/ConvertExtension ?
> >>> 
> >>> I don't know the state of monotone support in mercurial, but I've never
> >>> used monotone, so...
> >> 
> >> Convert should work. If not, feel encouraged to give me the right mtn 
> >> spell to get a clone of your mtn and I'll gladly poke it to see what's 
> >> wrong.
> > 
> > The monotone converter gets confused by me doing 
> > rename "" -> "libtomcrypt" on one side of the merge in
> > revision fdf4a7a3b97ae5046139915de7e40399cceb2c01. That
> > happens via monotone's "merge_into_dir" command - I moved
> > the root directory of the ...ltc.dropbear  branch into a
> > subdirectory of the main dropbear branch.
> > 
> > The end result is that an old version of "changes" appears
> > in the toplevel directory of au.asn.ucc.matt.dropbear
> > branch, as well as the correct version at
> > "libtomcrypt/changes". (The same happens for various other
> > files there too).
> > 
> > Looking at the code in montone.py's getchanges() I can't see
> > how it would work correctly. It's iterating over all
> > renames/adds/deletes, but in a merge each operation will be
> > relative a particular parent revision denoted by the
> > "old_revision" lines.  See
> > http://matt.ucc.asn.au/dropbear/test/fdf4a7a-merge_into_dir.txt
> > for the Monotone revision (from "mtn automate
> > get_revision").
> > 
> > I've tried a few different tweaks but none seemed to 
> > improve things. Unfortunately a simple synthetic testcase
> > doesn't hit the same problem either :(
> > I might try making a simpler getchanges() version that
> > ignores renames and just uses mtn automate's get_manifest_of
> > to figure out the files - my repository I can live without
> > rename/copy tracking.
> > 
> > If you want to look at it I also needed the following for
> > the empty fromdir case to avoid paths with a leading slash.
> > 
> > if fromdir == "":
> >    renamed[tofile] = fromdir + tofile[len(todir)+1:]
> > else:
> >    renamed[tofile] = fromdir + tofile[len(todir):]
> > 
> > I also had to comment out the mercurial_source in convcmd.py
> > - otherwise it would abort before the monotone source was
> > tried. I'll report that one as a separate bug, I assume it
> > would affect any converter below mercurial_source.
> > 
> > I've put a cut down repository at
> > http://matt.ucc.asn.au/dropbear/test/small-dropbear.mtn
> > 
> > Cheers,
> > Matt
> 
--- monotone.py.orig	2011-11-28 21:13:58.000000000 +0800
+++ monotone.py	2011-11-28 21:14:55.000000000 +0800
@@ -224,62 +224,30 @@ class monotone_source(converter_source, 
         else:
             return [self.rev]
 
+    def manifest_files(self, rev):
+        manifest = self.mtnrun("get_manifest_of", rev).split("\n\n")
+
+        filenames = []
+        for l in manifest:
+            m = self.file_re.match(l)
+            if not m:
+                continue
+            name = m.group(1)
+            filenames.append(name)
+        return filenames
+
     def getchanges(self, rev):
-        #revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
-        revision = self.mtnrun("get_revision", rev).split("\n\n")
-        files = {}
-        ignoremove = {}
-        renameddirs = []
-        copies = {}
-        for e in revision:
-            m = self.add_file_re.match(e)
-            if m:
-                files[m.group(1)] = rev
-                ignoremove[m.group(1)] = rev
-            m = self.patch_re.match(e)
-            if m:
-                files[m.group(1)] = rev
-            # Delete/rename is handled later when the convert engine
-            # discovers an IOError exception from getfile,
-            # but only if we add the "from" file to the list of changes.
-            m = self.delete_re.match(e)
-            if m:
-                files[m.group(1)] = rev
-            m = self.rename_re.match(e)
-            if m:
-                toname = m.group(2)
-                fromname = m.group(1)
-                if self.mtnisfile(toname, rev):
-                    ignoremove[toname] = 1
-                    copies[toname] = fromname
-                    files[toname] = rev
-                    files[fromname] = rev
-                elif self.mtnisdir(toname, rev):
-                    renameddirs.append((fromname, toname))
-
-        # Directory renames can be handled only once we have recorded
-        # all new files
-        for fromdir, todir in renameddirs:
-            renamed = {}
-            for tofile in self.files:
-                if tofile in ignoremove:
-                    continue
-                if tofile.startswith(todir + '/'):
-                    renamed[tofile] = fromdir + tofile[len(todir):]
-                    # Avoid chained moves like:
-                    # d1(/a) => d3/d1(/a)
-                    # d2 => d3
-                    ignoremove[tofile] = 1
-            for tofile, fromfile in renamed.items():
-                self.ui.debug (_("copying file in renamed directory "
-                                 "from '%s' to '%s'")
-                               % (fromfile, tofile), '\n')
-                files[tofile] = rev
-                copies[tofile] = fromfile
-            for fromfile in renamed.values():
-                files[fromfile] = rev
+        files = []
+
+        fns = self.manifest_files(rev)
+        files.extend((f, rev) for f in fns)
+
+        parents=self.mtnrun("parents", rev).splitlines()
+        for p in parents:
+            fns = self.manifest_files(p)
+            files.extend((f, rev) for f in fns)
 
-        return (files.items(), copies)
+        return files, {}
 
     def getfile(self, name, rev):
         if not self.mtnisfile(name, rev):

Reply via email to