{"id":98,"date":"2009-03-12T13:46:40","date_gmt":"2009-03-12T11:46:40","guid":{"rendered":"http:\/\/www.gijsk.com\/blog\/?p=98"},"modified":"2009-03-13T11:26:50","modified_gmt":"2009-03-13T09:26:50","slug":"moving-from-cvs-to-mercurial","status":"publish","type":"post","link":"https:\/\/www.gijsk.com\/blog\/2009\/03\/moving-from-cvs-to-mercurial\/","title":{"rendered":"Moving from CVS to Mercurial"},"content":{"rendered":"<p>Yesterday, Venkman <a href=\"https:\/\/bugzilla.mozilla.org\/show_bug.cgi?id=475012\">moved<\/a> from <a href=\"http:\/\/mxr.mozilla.org\/seamonkey\/source\/extensions\/venkman\/\">CVS<\/a> to <a href=\"http:\/\/hg.mozilla.org\/venkman\/\">Hg<\/a>. For the benefit of others who may want to move other extensions, here is a rough attempt to outline the steps I took.<\/p>\n<p>First, some notes of caution:<\/p>\n<ul>\n<li>HG uses a character encoding specific to your machine. For my mac, that turned out to be mac-roman. You usually don&#8217;t want that, and need to tell it you want it to use utf8 instead. I could actually not convince it to do this for the author map &#8211; it stored the authors in mac-roman anyway. Check your imports carefully.<\/li>\n<li>HG&#8217;s default <a href=\"http:\/\/www.selenic.com\/mercurial\/wiki\/index.cgi\/ConvertExtension\">ConvertExtension<\/a> is your friend, as long as you tell it what to do the right way.<\/li>\n<li>You probably want to create a test repo (I ended up using several, in trial and error!) at hg.mozilla.org\/users. Instructions for doing that may be found <a href=\"https:\/\/developer.mozilla.org\/en\/Publishing_Mercurial_Clones\">here<\/a>. Keep in mind that once you stick something in a Mercurial repo, <strong>it will be there forever<\/strong>. This means anyone pulling from your repo will have to keep downloading all those files. Be careful about what you push to the repo, because once you&#8217;ve pushed something there&#8217;s no going back (short of asking IT to delete the repo and trying again).<\/li>\n<\/ul>\n<p>Alright. Down to the actual import. Here is the actual steps I ended up following. When I say &#8220;ended up&#8221; I mean &#8220;after trying N different things which didn&#8217;t work&#8221;, where N was large enough to keep me busy for a fair number of hours.<\/p>\n<ol>\n<li>Check out the relevant code from CVS. In my case, this meant:\n<pre>cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:\/cvsroot co mozilla\/extensions\/venkman<\/pre>\n<\/li>\n<li>Enable the convert and mq extensions. Edit your ~\/.hgrc file and include:\n<pre>[extensions]\r\nhgext.convert=\r\nmq =<\/pre>\n<\/li>\n<li>Decide whether you want all the branches in CVS. If, like me, you&#8217;re importing an extension, you probably don&#8217;t care about the Firefox\/Mozilla release branches. You just want trunk history. In order to do this, we ask the convert extension to split up branches. Edit your <code>~\/.hgrc<\/code> file and include:\n<pre>[convert]\r\nhg.usebranchnames=0\r\nhg.clonebranches=1<\/pre>\n<\/li>\n<li>Now you can run convert, more or less like this:\n<pre>hg --encoding utf8 convert vnkCVS\/mozilla\/extensions\/venkman venkman-initial<\/pre>\n<\/li>\n<li>Inspect your handiwork: you will now end up with several directories, one for each branch. You presumably want &#8220;default&#8221;, which should correspond to trunk. We will convert from hg to hg in a bit, to obtain just that.\u00c2\u00a0 Go back to your <code>~\/.hgrc<\/code> file and remove the <code>[convert]<\/code> section you added in step 3. This way, the new repo we&#8217;ll convert to won&#8217;t still have the &#8220;default&#8221; directory.<\/li>\n<li>Additionally, we still need to map authors. CVS used something like: &#8220;foo%somecompany.com&#8221;, and in Mercurial, we expect something of the form &#8220;John Doe &lt;johndoe@mozilla.com&gt;&#8221;. So we need to define an author map file, in which each line simply maps one set of authors to the next. For example:<br \/>\n<code>johndoe%mozilla.com = John Doe &lt;johndoe@mozilla.com&gt;<\/code> . I uploaded the <a href=\"http:\/\/www.gijsk.com\/blog\/wp-content\/uploads\/2009\/03\/fullmap.txt\">Author map for Venkman CVS to hg import<\/a> that I used. It probably does not cover everyone who committed to your repo. If there are aliases that you&#8217;re not familiar with (Mozilla CVS is pretty old!) then Google and asking on IRC are easy ways of figuring out who&#8217;s who. To create a complete author map, I used some ad-hoc sed magic on:<\/p>\n<pre>\r\nhg log | grep \"user:\" &gt; foo.txt\r\n<\/pre>\n<\/li>\n<li>You may want to unify the entries of committers who have committed using different committer IDs. <a href=\"http:\/\/www.ohloh.net\/\">Ohloh<\/a> can help there.<\/li>\n<li>Run hg convert again:\n<pre>hg --encoding utf8 convert --authors myAuthorMap.txt venkman-initial\/default\/ venkman-final\/<\/pre>\n<\/li>\n<li>Check <code>hg log<\/code>. If there are loads of tags in which you&#8217;re not interested, you can use the <code>hg strip<\/code> command to strip the last hg revision, which added all the tags.<\/li>\n<li>Verify everything worked. Then add the correct &#8220;default-push&#8221; line to the <code>.hg\/hgrc<\/code> file for the new repo you created, and push to your user repo. Check that everything is correct by reviewing the hgweb overview of things. If so, change the default-push line to point to the &#8220;real&#8221; repo, and push all the changesets there. You&#8217;re done!<\/li>\n<\/ol>\n<p>This may not be the easiest or best way to do things, but that&#8217;s the way I managed &#8211; suggestions\/improvements appreciated!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yesterday, Venkman moved from CVS to Hg. For the benefit of others who may want to move other extensions, here is a rough attempt to outline the steps I took. First, some notes of caution: HG uses a character encoding &hellip; <a href=\"https:\/\/www.gijsk.com\/blog\/2009\/03\/moving-from-cvs-to-mercurial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,2,16],"tags":[],"class_list":["post-98","post","type-post","status-publish","format-standard","hentry","category-chatzilla","category-mozilla","category-venkman"],"_links":{"self":[{"href":"https:\/\/www.gijsk.com\/blog\/wp-json\/wp\/v2\/posts\/98"}],"collection":[{"href":"https:\/\/www.gijsk.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gijsk.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gijsk.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gijsk.com\/blog\/wp-json\/wp\/v2\/comments?post=98"}],"version-history":[{"count":29,"href":"https:\/\/www.gijsk.com\/blog\/wp-json\/wp\/v2\/posts\/98\/revisions"}],"predecessor-version":[{"id":102,"href":"https:\/\/www.gijsk.com\/blog\/wp-json\/wp\/v2\/posts\/98\/revisions\/102"}],"wp:attachment":[{"href":"https:\/\/www.gijsk.com\/blog\/wp-json\/wp\/v2\/media?parent=98"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gijsk.com\/blog\/wp-json\/wp\/v2\/categories?post=98"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gijsk.com\/blog\/wp-json\/wp\/v2\/tags?post=98"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}