Migrating Mercurial

I'm in the middle of moving to a new shared web host (Webfaction to Opalstack [affiliate link]). Migrating web hosts is a pain in the ass.

Besides hosting a few low-traffic websites (like this one), I also use my shared host to keep a copy of my Mercurial repositories.  This acts as both an offsite backup for my code and a convenient way to synchronize code repositories with my employees.  Although Mercurial is a distributed version control system, it's still useful to have a central repository location.

I use TortoiseHg as a front-end for Mercurial.  TortoiseHg includes a sync window which displays saved paths to remote repositories.  I use named PuTTY sessions to create URL paths to my remote repos.  Here's an example:

The default remote repository is connecting via ssh to my webfaction named PuTTY session.  The next part of the URL is the path to the repository folder on my web host: /home/mwolfe02/webapps/hg/repos/ and the last part of the path is the repository name, loan_mgmt.

As part of the migration, I need to change the default alias to the new Opalstack host.  I still want to keep a copy of the path to my old Webfaction location until I finish my migration.  I can do this manually through the TortoiseHg interface.  Here are the results:

I updated the default alias to reflect the new Opalstack host location.  I then gave the old default location a new alias of webfaction.

This only took a couple of minutes.  No big deal.  Except that I have 120 repositories on my shared host (you read that right...I version control everything).  A couple of minutes times 120 turns into an entire morning pretty quickly.  Not to mention, I need to do this on all of my development machines.  I needed an automated solution.

I turned to Notepad++ and its handy Find in Files feature.  The repository path aliases are saved in a file named .hg\hgrc.  Here's the updated file for the above repository:

Basically, what I needed to do was replace this text...

default = ssh://webfaction//home/mwolfe02/webapps/hg/repos/loan_mgmt

...with this text:

default = ssh://opal//home/gb/repos/loan_mgmt
webfaction = ssh://webfaction//home/mwolfe02/webapps/hg/repos/loan_mgmt

Of course, the final folder name ("loan_mgmt" in the samples above) would be different for each .hgrc file.

Here's how I updated all of my individual repositories' settings in a few seconds instead of several hours.  You can play with the regular expression and replacement expression at regex101.com (custom link with regex info prefilled).

  1. Find what: default = ssh:\/\/webfaction\/\/home\/mwolfe02\/webapps\/hg\/repos\/(.*)$
  2. Replace with: default = ssh://opal//home/gb/repos/$1\nwebfaction = ssh://webfaction//home/mwolfe02/webapps/hg/repos/$1
  3. Filters: hgrc (the name of the Mercurial repository settings file)
  4. Directory: {Parent directory of a single repository to prove the concept; then switch to grandparent directory to update multiple repositories}
  5. Search Mode: (o) Regular expression
  6. [√] In all sub-folders
  7. Click [Find All] to validate the search string is correct
  8. Click [Replace in Files] to perform the replacement (you'll have to re-open the Find in Files dialog after step 7 above)

Notice that in Step 4, I'm using the folder for a single repository.  Once I tested and verified my regex worked the way I wanted, I changed the Directory to a "grandparent" folder: M:\Repos.  That change, along with the search [√] In all sub-folders option, is what ultimately allowed me to update every local repository with the new URL paths.

Photo by Gary Bendig on Unsplash