convert_svn ("release early" edition)

Brendan Cully brendan at kublai.com
Sat Jun 30 19:03:58 CDT 2007


On Saturday, 30 June 2007 at 15:05, Daniel Holth wrote:
> Brendan Cully wrote:
> > On Sunday, 11 February 2007 at 23:47, Daniel Holth wrote:
> >> convert-repo patched to convert from Subversion.
> >>
> >> http://dingoskidneys.com/cgi-bin/hgwebdir.cgi/outgoing (patches applied)
> >> http://dingoskidneys.com/cgi-bin/hgwebdir.cgi/queue-convert-svn (just
> >> the patches)
> >
> > Here's an update to 0.9.4. I can't really test it yet since my svn
> > 1.4.3 bindings don't seem to return the right information from
> > get_dir2. But this patch does allow convert to churn for a while
> > before bailing out :)
> Brendan,
> 
> Thanks! You've encouraged me to work on it some more. I merged my
> changes with your changes and Eduoard's changes, and the result is at
> http://dingoskidneys.com/cgi-bin/hgwebdir.cgi/convert-queue-crew-dholth

Excellent. Here's a patch that makes it appear to function with my
subversion 1.4.3 swig bindings. The 'mark' messages look not quite
right, and it gobbles an absolutely insane amount of RAM even
converting 100 revisions at a time on my powerbook, but it seems to be
working. I don't understand its approach to branches though. It seems
like maybe it should get the last revisions for trunk and
subdirectories of branches and use those as heads?
-------------- next part --------------
# HG changeset patch
# User Brendan Cully <brendan at kublai.com>
# Date 1183247948 25200
# Node ID 6b3eab5d9ee471c064aa9a64e8c3ffddf25bfc3b
# Parent  535db6e6bcf59d3548f42359e58de0405d839814
Add compatibility with SVN 1.4.3 bindings

diff --git a/series b/series
--- a/series
+++ b/series
@@ -1,12 +1,13 @@
-./generic/fix-save-map-opens.patch
-./generic/enh-user-map-support.patch
-./generic/enh-init-dst-after-src.patch
+./generic/fix-save-map-opens.patch #+applied
+./generic/enh-user-map-support.patch #+applied
+./generic/enh-init-dst-after-src.patch #+applied
 
 # SVN backend
 ./svn/enh-add-svn-transport.patch
 ./svn/enh-add-svn-converter.patch
+./svn/compat-1.4.3.patch
 
 # CVS stuff for some projects
-./generic/enh-add-parent-to-puttags.patch
-./cvs/enh-tags-on-same-branch.patch
-./cvs/enh-add-cvsps-hand-surgery.patch
+./generic/enh-add-parent-to-puttags.patch #+review
+./cvs/enh-tags-on-same-branch.patch #+review
+./cvs/enh-add-cvsps-hand-surgery.patch #+review
diff --git a/svn/compat-1.4.3.patch b/svn/compat-1.4.3.patch
new file mode 100644
--- /dev/null
+++ b/svn/compat-1.4.3.patch
@@ -0,0 +1,92 @@
+svn: handle slightly older subversion bindings (tested with 1.4.3)
+
+With these bindings, ra.get_dir2? returns a dictionary of properties,
+but no entries. A fallback using client.ls is used if this case is
+detected.
+
+The recode method doesn't handle None, so some input is pretested.
+
+ra.get_log seems to return entries that are already in the form
+svn_paths converts to, so this class is made to essentially pass
+through the input if it detects this.
+
+diff --git a/hgext/convert/common.py b/hgext/convert/common.py
+--- a/hgext/convert/common.py
++++ b/hgext/convert/common.py
+@@ -94,3 +94,12 @@ class converter_sink(object):
+         """Put tags into sink.
+         tags: {tagname: sink_rev_id, ...}"""
+         raise NotImplementedError()
++
++def recode(s):
++    try:
++        return s.decode("utf-8").encode("utf-8")
++    except:
++        try:
++            return s.decode("latin-1").encode("utf-8")
++        except:
++            return s.decode("utf-8", "replace").encode("utf-8")
+diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py
+--- a/hgext/convert/subversion.py
++++ b/hgext/convert/subversion.py
+@@ -42,6 +42,12 @@ class svn_paths(object):
+     def __init__(self, orig_paths):
+         self.order = []
+         self.values = {}
++        if hasattr(orig_paths, 'keys'):
++            self.order = sorted(orig_paths.keys())
++            self.values.update(orig_paths)
++            return
++        if not orig_paths:
++            return
+         for path in orig_paths:
+             self.order.append(path)
+             self.values[path] = svn_entry(orig_paths[path])
+@@ -356,13 +362,14 @@ class convert_svn(converter_source):
+                 # ISO-8601 conformant
+                 # '2007-01-04T17:35:00.902377Z'
+                 date = util.parsedate(date[:18] + " UTC", ["%Y-%m-%dT%H:%M:%S"])
+-                log = recode(message)
++                log = message and recode(message) or ''
++                author = author and recode(author) or ''
+ 
+                 if log.strip() == "":
+                     log = u"*** empty log message ***\n".encode("utf-8")
+                 log += "\n\n" + recode(rev)
+ 
+-                cset = commit(author=recode(author) or "", 
++                cset = commit(author=author, 
+                         date=util.datestr(date), 
+                         desc=log, 
+                         parents=[],
+@@ -447,6 +454,19 @@ class convert_svn(converter_source):
+         return []
+ 
+     def _find_children(self, path, revnum):
++        def _find_children_fallback(path, revnum):
++            # SWIG python bindings for getdir are broken up to at least 1.4.3
++            if not hasattr(self, 'client_ctx'):
++                self.client_ctx = svn.client.create_context()
++            optrev = svn.core.svn_opt_revision_t()
++            optrev.kind = svn.core.svn_opt_revision_number
++            optrev.value.number = revnum
++            rpath = '/'.join([self.url, path]).strip('/')
++            return svn.client.ls(rpath, optrev, True, self.client_ctx).keys()
++
++        if hasattr(self, '_find_children_fallback'):
++            return _find_children_fallback(path, revnum)
++
+         pool = Pool()
+         path = path.strip("/")
+         self.reparent("/" + path)
+@@ -458,6 +478,10 @@ class convert_svn(converter_source):
+                 getdir = svn.ra.get_dir2(self.ra, path, revnum, fields, pool)
+             else:
+                 getdir = svn.ra.get_dir(self.ra, path, revnum, pool)
++            if type(getdir) == dict:
++                # python binding for getdir is broken up to at least 1.4.3
++                self._find_children_fallback = True
++                return _find_children_fallback(path, revnum)
+             dirents = getdir[0]
+             if type(dirents) == int:
+                 print "integer"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 186 bytes
Desc: not available
Url : http://selenic.com/pipermail/mercurial-devel/attachments/20070630/dfb90f41/attachment.pgp 


More information about the Mercurial-devel mailing list