Getting Mercurial Running on DreamHost Part II: Cloning an Existing Local Repo to the Server and Making it the Parent
Last time, we talked about getting Mercurial running on Dreamhost, which should be enough to allow you to start creating repos on the server (using hg init while ssh’d in) and cloning them locally. But what if you already have repos with a rich history on your local machine and want to clone them to the server? I promise it’s easy, but I’d like to make a quick digression because something’s been bugging me.
I’ve always wondered why Mercurial’s executable was called hg. I thought that maybe it was a holdover from an ancestor project- the way Firefox’s executable was called mozilla for a while. It turns out that I was selling Mercurial’s developers short and that they do, in fact, have their shit together:
It was named after the elemental symbol for mercury, Hg. The Mercurial Logo even looks like a glop of Mercury.
The symbol Hg is short for hydrargyrum which comes from the Latinized Greek prefix hyrda- meaning watery or runny and the word argyros meaning silver. So it means runny silver. I can imagine the Greeks making prank phone calls: “Is your silver runny? Then you better go catch it!” and getting people all mad and Latinized over it. Anyway, back to
3. Clone my existing local repositories to the server and then make that server the parent
Should be easy, right? It is. Ned Batchelder’s answer to this Stack Overflow question nails it. First, ssh into your Dreamhost account, then create a new repository on the server to house the repo that’s already on your local machine. Make sure that it’s in the repo parent directory (specified in hgweb.config) so that hgweb.cgi will pick it up.
cd ~/hg/repos mkdir HotPotato cd HotPotato hg init
Now logout of your ssh session and use Terminal to navigate to the local directory of the repository you want to clone to the server. Use the hg push command to get the local repo up to your newly created server repo.
hg push ssh://TheBestHuman@pr.ogra.ms/hg/repos/HotPotato
Make sure you put the ssh:// prefix on the URI or you’ll get a repository not found error message. Now you should be able to go to hgweb.cgi and see your new (old) repo.
Your repo is available on the server, but we need to make it so that when you hg push from your local repo, it remembers what server to push to. This will make it so you don’t have to specify the server repo’s URI every time you want to push your changes up.
with vi open, add the following lines to the hgrc file.
[paths] default = ssh://TheBestHuman@pr.ogra.ms/hg/repos/HotPotato
Any changes you commit locally from now on will get pushed to the server if you run hg push!
But wait, if you ssh back in to the server and ls in the new repo’s directory, you won’t see any files!
What was all that console output if it wasn’t uploading the repo to the server? And how come when you navigate to hgweb.cgi, there’s a bunch of history about files that don’t seem to exist? Well, it has to do with some Mercurial fundamentals. The repo’s root directory (~/hg/repos/HotPotato) contains the working copy of the repo. Mercurial, however, only cares about committed code. Since we hg pushed the local repo to the server, Mercurial is aware of the changes, but has not applied those changes to the working copy on the server. The changes are all sitting in the .hg subfolder (~/hg/repos/HotPotato/.hg). If you never want to work on code and commit changes from the server, this is fine. It doesn’t really matter what the working copy on the server contains. But if you ever want to be able to edit code directly from an ssh session on the server, you’ll have to bring the working copy up to date.
You’ll also have to do this from any repo that you clone from the server copy.
And that’s it! Don’t worry, the workflow seems like a lot to remember but it will start to feel really natural after a while.