{"thread":{"id":"7423","subject":"an hg-to-git adventure","startedAt":"2007-03-27T09:43:38Z","lastAt":"2007-03-27T11:33:32Z","messageCount":2,"participants":["Jim Meyering","Theodore Tso"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"38123","messageId":"87tzw7qawl.fsf@rho.meyering.net","threadId":"7423","inReplyTo":null,"subject":"an hg-to-git adventure","fromName":"Jim Meyering","fromEmail":"jim@meyering.net","sentAt":"2007-03-27T09:43:38Z","receivedAt":"2007-03-27T09:43:38Z","isPatch":false,"sender":{"key":"jim@meyering.net","avatar":"https://avatars.githubusercontent.com/u/710630?v=4"},"body":"Normally, converting a mercurial repository to git is simple: just\nrun the hg-to-git script (from git/contrib).  However, the one I did\nyesterday was different.\n\nQuick summary:\n\n    I had to hack python not to barf on a delta involving .hg/hgrc,\n    and to make hg-to-git work even when there are no files to commit.\n\nHere are the details, in case someone else encounters the same problem.\n\nThe trouble with that particular hg repository is that the special file,\n.hg/hgrc, is under version control.  Earlier versions of Mercurial allowed\nthat, but new ones do not, and part of the hg-to-git script runs \"hg\nupdate -C N\" for each change-set number, N, and that \"update\" command\nfails for any change set that includes a file in the .hg/ admin directory.\n\nThe very first change set adds just one file, .hg/hgrc.  Because\nthat file is in .hg/, \"hg update -C 0\" would fail with this diagnostic:\n\n  \"path contains illegal component: .hg/hgrc\"\n\nThat looked easy to work around.  Just hack hg not to perform that check.\nIt turns out this approach is fine, since hg-to-git doesn't use the\nexplicit file list from mercurial, but rather simply git-commits all\nchanges brought in by the \"hg update\".  That means changes to .hg/*\nadmin files are ignored, which is perfect.  Here's the patch: (obviously,\nintended solely for private, temporary use)\n\ndiff -r 0ce23256e454 mercurial/util.py\n--- a/mercurial/util.py\tSat Mar 24 13:31:43 2007 +0100\n+++ b/mercurial/util.py\tMon Mar 26 22:12:12 2007 +0200\n@@ -652,10 +652,6 @@ def copyfiles(src, dst, hardlink=None):\n\n def audit_path(path):\n     \"\"\"Abort if path contains dangerous components\"\"\"\n-    parts = os.path.normcase(path).split(os.sep)\n-    if (os.path.splitdrive(path)[0] or parts[0] in ('.hg', '')\n-        or os.pardir in parts):\n-        raise Abort(_(\"path contains illegal component: %s\\n\") % path)\n\n def _makelock_file(info, pathname):\n     ld = os.open(pathname, os.O_CREAT | os.O_WRONLY | os.O_EXCL)\n\nTo my surprise, that did not help.  I'd built and installed\nmercurial into its own hierarchy with this command:\n\n  python setup.py install --home=/p/p/hg-2007-03-26.20h24\n\nthen added /p/p/hg-2007-03-26.20h24/bin at the front of my PATH.\nIt turns out that the 2-line \"hg\" driver script was not using the\njust-installed libraries.  So I changed /p/p/hg-2007-03-26.20h24/bin/hg,\ninserting these two lines after the #! one:\n\n  import sys\n  sys.path.insert(0, \"/p/p/hg-2007-03-26.20h24/lib/python\")\n\n[there's probably a way to do this with some PYTHON*\n envvar, but I prefer not to rely on envvar settings here ]\n\nAnd that did the job, in that hg-to-git got past the initial failure.\nHowever, it went only a few lines farther before failing anew, this\ntime because it tried to extract a substring (an SHA1 checksum) from the\nempty string -- that happened because there were no files to git-commit\nfor that first change set.  The following patch works around that case:\n\ndiff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py\nindex 37337ff..9fbc1d5 100755\n--- a/contrib/hg-to-git/hg-to-git.py\n+++ b/contrib/hg-to-git/hg-to-git.py\n@@ -218,7 +218,10 @@ for cset in range(int(tip) + 1):\n\n     # retrieve and record the version\n     vvv = os.popen('git-show | head -1').read()\n-    vvv = vvv[vvv.index(' ') + 1 : ].strip()\n+    if vvv:\n+        vvv = vvv[vvv.index(' ') + 1 : ].strip()\n+    else:\n+        vvv = '0';\n     print 'record', cset, '->', vvv\n     hgvers[str(cset)] = vvv\n\nand once it got past that first change set, hg-to-git (using\nthe hacked \"hg\") converted the remaining 431 change sets.\n\nFWIW, I also tried tailor, but it did no better than stock hg-to-git.\nIt might have worked with the hacked \"hg\", but I didn't try that.\n\nBottom line, I now have a git repo, and other conversions should be trivial.\n"},{"id":"38146","messageId":"20070327113332.GA469@thunk.org","threadId":"7423","inReplyTo":"87tzw7qawl.fsf@rho.meyering.net","subject":"Re: an hg-to-git adventure","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-03-27T11:33:32Z","receivedAt":"2007-03-27T11:33:32Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Tue, Mar 27, 2007 at 11:43:38AM +0200, Jim Meyering wrote:\n> Normally, converting a mercurial repository to git is simple: just\n> run the hg-to-git script (from git/contrib).  However, the one I did\n> yesterday was different.\n\nBy the way, there is a faster hg-to-git script called hg-fast-export\nlocated inside the fast-export repository:\n\n\tgit://repo.or.cz/fast-export.git\n\nThis uses git-fast-import and does a much faster conversion job.  It\nalso has some features to clean up author names (including pulling out\nSigned-Off-By: information so it can be stuffed into the author field)\nautomatically.\n\n\t\t\t\t\t\t- Ted\n"}]}