{"id":116,"date":"2008-10-14T10:22:14","date_gmt":"2008-10-14T15:22:14","guid":{"rendered":"http:\/\/blog.red-bean.com\/sussman\/?p=116"},"modified":"2009-10-07T19:27:40","modified_gmt":"2009-10-08T00:27:40","slug":"a-mercurial-super-client","status":"publish","type":"post","link":"http:\/\/blog.red-bean.com\/sussman\/?p=116","title":{"rendered":"a Mercurial &#8220;super client&#8221;"},"content":{"rendered":"<p>One of the cool trends I&#8217;ve seen is the use of distributed version control systems as &#8220;super clients&#8221; against Subversion.   You suck down the entire history of a Subversion repository into a local, private repository, do all of your commits locally, make branches, experiment all you want, then &#8220;push&#8221; back up to Subversion again.  On the internet, nobody knows you&#8217;ve been using DVCS (or that <a href=\"http:\/\/en.wikipedia.org\/wiki\/On_the_Internet,_nobody_knows_you%27re_a_dog\">you&#8217;re a dog<\/a>.)  What&#8217;s particularly cool about these bridging tools is that they allow users to try out DVCS before deciding to officially convert a whole project over.  Or, if a project happens to be using Subversion but you still want most of the power of a DVCS for local work, it&#8217;s a perfect solution.<\/p>\n<p>For all the blabbing I&#8217;ve done about distributed version control systems, I&#8217;m still a big fan of <a href=\"http:\/\/www.selenic.com\/mercurial\/wiki\/\">Mercurial<\/a>.    Of all the DVCSes, I think it&#8217;s the easiest to learn for svn users.  It has a small, tight set of commands, and the community which runs the project is polite and sane.<\/p>\n<p>In any case, there have been a <a href=\"http:\/\/www.selenic.com\/mercurial\/wiki\/index.cgi\/WorkingWithSubversion\">collection of Mercurial-Subversion bridges<\/a> available for the last couple of years, but they&#8217;ve all been deficient in various ways:  either not capturing svn history entirely, or being unable to push back to svn correctly (or only very awkwardly).  So I&#8217;ve pretty much stayed away.  But today I want to plug a new bridge written by a friend of mine (<a href=\"http:\/\/durin42.blogspot.com\/\">Augie Fackler<\/a>) who finally did it Right:  he wrote a bridge called <a href=\"http:\/\/www.bitbucket.org\/durin42\/hgsubversion\/wiki\/Home\">hgsubversion<\/a> which (1) uses the actual Subversion API to pull history down (which is faster, more accurate, and long-term sustainable), and (2) actually knows how to push changes back to Subversion correctly.  I want the world to be aware of this tool, because I think it&#8217;s the first Mercurial-Subversion bridge which deserves to be promoted into the popular ranks with tools like <a href=\"http:\/\/www.kernel.org\/pub\/software\/scm\/git\/docs\/git-svn.html\">git-svn<\/a>.<\/p>\n<p>The tool is still young and not generally installable by the public (i.e. you&#8217;re not going to find any magic .rpm, .dpkg, .zip or .dmg for it yet)&#8230; but here are my cliff notes if you want to start playing with it.<\/p>\n<p><b>Requirements<\/b><\/p>\n<ul>\n<li>The latest (unreleased) Mercurial<\/li>\n<li>Local Subversion libraries, at least 1.5, with swig-python bindings built<\/li>\n<li>A Subversion server that is 1.4 or later<\/li>\n<\/ul>\n<p><b>To get the latest Mercurial:<\/b><br \/>\n<code><br \/>\n$ hg clone http:\/\/selenic.com\/repo\/hg hg-latest<br \/>\n$ cd hg-latest<br \/>\n$ make<br \/>\n$ sudo make install<br \/>\n<\/code><\/p>\n<p><b>To get the latest Subversion python bindings:<\/b><br \/>\n<code><br \/>\n$ # if you don't have a binary package for svn-1.5-python-bindings already,<br \/>\n$ # this is a summary of subversion\/bindings\/swig\/INSTALL instructions:<br \/>\n$ svn checkout http:\/\/svn.collab.net\/repos\/svn\/tags\/1.5.3 svn<br \/>\n$ cd svn<br \/>\n$ .\/autogen.sh && .\/configure<br \/>\n$ make<br \/>\n$ sudo make install<br \/>\n$ make swig-py  # make sure you have swig 1.3 installed already<br \/>\n$ make check-swig-py<br \/>\n$ sudo make install-swig-py<br \/>\n<\/code><\/p>\n<p><b>To get hgsubversion:<\/b><br \/>\n<code><br \/>\n$ hg clone http:\/\/bitbucket.org\/durin42\/hgsubversion\/ ~\/hgsubversion<br \/>\n$ cat >> ~\/.hgrc<br \/>\n[extensions]<br \/>\nrebase=<br \/>\nsvn=\/home\/user\/hgsubversion<br \/>\n^D<br \/>\n<\/code><\/p>\n<p>To make sure you&#8217;re ready to go, do a final sanity check:<\/p>\n<p><code><br \/>\n$ python -c \"import svn.core; print svn.core.SVN_VER_MINOR\"<br \/>\n5<br \/>\n$ # if you get something less than 5, you may have conflicting<br \/>\n$ # versions installed, and may need to set PYTHONPATH<br \/>\n<\/code><\/p>\n<p>Now you can clone your favorite svn repository, and use it locally:<\/p>\n<p><code><br \/>\n$ hg svnclone http:\/\/svn.example.com\/repos hg-repos<br \/>\nconverting r1 by joe<br \/>\nA trunk\/<br \/>\ncommitted as 24dfb7b51d606a921333e2b8f19a9a6aa5661a69 on branch default<br \/>\n[...]<br \/>\nconverting r100 by jane<br \/>\nM trunk\/goo<br \/>\nM trunk\/moo<br \/>\ncommitted as 54dfb7b51d6d6a931333e2b8f19a9a6005661a62 on branch default<br \/>\n$<br \/>\n<\/code><\/p>\n<p>The tool currently assumes a &#8216;standard&#8217; svn layout of \/trunk, \/branches, \/tags, and then tries to pull them into sane mercurial equivalents.  After you&#8217;ve made a bunch of local commits, you can push the changes back to subversion:<\/p>\n<p><code><br \/>\n$ # First merge the latest public svn changes into your repository:<br \/>\n$ hg svn pull<br \/>\nconverting r101 by pinky<br \/>\nA trunk\/awesomefile<br \/>\ncommitted as e85afd44dc83d5df2599157096a95b0868de6955 on branch default<br \/>\n$ hg up -C<br \/>\n3 files updated, 0 files merged, 1 files removed, 0 files unresolved<br \/>\n$ # We now have two hg HEADs, because the public svn changes are<br \/>\n$ # considered a different line of development from my own.<br \/>\n$ # For now, rebasing is preferred to merging:<br \/>\n$ hg up -C 9985f017b3ab<br \/>\n3 files updated, 0 files merged, 1 files removed, 0 files unresolved<br \/>\n$ hg svn rebase<br \/>\nsaving bundle to \/home\/user\/project\/.hg\/strip-backup\/c4b9dfce6b09-temp<br \/>\nadding branch<br \/>\nadding changesets<br \/>\nadding manifests<br \/>\nadding file changes<br \/>\nadded 4 changesets with 4 changes to 4 files<br \/>\nrebase completed<br \/>\n$ # At the moment, each changeset is pushed separately;<br \/>\n$ # changeset flattening not yet implemented<br \/>\n$ hg svn push<br \/>\n<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the cool trends I&#8217;ve seen is the use of distributed version control systems as &#8220;super clients&#8221; against Subversion. You suck down the entire history of a Subversion repository into a local, private repository, do all of your commits locally, make branches, experiment all you want, then &#8220;push&#8221; back up to Subversion again. On [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-116","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/posts\/116","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=116"}],"version-history":[{"count":18,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/posts\/116\/revisions"}],"predecessor-version":[{"id":270,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=\/wp\/v2\/posts\/116\/revisions\/270"}],"wp:attachment":[{"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=116"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=116"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.red-bean.com\/sussman\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=116"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}