Did you know that you have to encode “#” in your path if you work with Mercurial (hg)? I didn’t.
Let’s say I have a repository named “work#A” and so the usual Mercurial usage:
$ hg clone ~/projects/work#A mybranch $ hg out ../work#A
wouldn’t work, and anything that requires path to a repository wouldn’t either as long you have a “#” in the path.
Excuse Me, What?
First of all you should read Mercurial’s manual on this, or if you fancy go grab a console and type:
$ hg help urls
The Mercurial guys decided to use “#” delimiter between repository path and revision. Does it sounds like a good feature to have? Can’t tell, I never use it but for me it smells like a legacy thing.
It’s A Feature Alright ..
Let’s say you have a can code in C# and you have projects under directory /media/c#/, so now you want to clone a project.
Unfortunately, if you are using Mercurial, you can’t do this:
$ hg clone /media/c#/mylinuxkernelrewrittenindotnet/ /tmp/dummybranch
to clone mylinuxkernelrewrittenindotnet to /tmp/dummybranch.
It will fail because it cannot find repository in /media/c. And if you DO have repository in /media/c, as long you dont have a tag named /mylinuxkernelrewrittenindotnet/ it will fail which is good because in this case we do not want to clone from /media/c up to tag /mylinuxkernelrewrittenindotnet/.
If you do have BOTH, a repository in /media/c and a tag named /mylinuxkernelrewrittenindotnet/ it will clone just that, successfully, but clearly it is not what you thought it is.
Wait, But I Thought Mercurial Is Intuitive?
Right away you thought you can escape this thing by adding a “\“, but nooo.. it wouldn’t work either.
So the Mercurial solution to this is to url-encode that path and put “file:” in front of the path expression. The end result should look like a URL.
Through research we know that a # url-encoded to %23. So with that knowledge, now you can do this:
$ hg clone file:/media/c%23/mylinuxkernelrewrittenindotnet/ /tmp/dummybranch
you can also use relative path as usual:
$ hg out file:../../../../work/foo%231
$ hg pull file:~/work/foo%232
which I have to admit is such a hassle. But really, the alternatives to this (in Mercurial) are:
- Just rename that stupid directory, or
- Avoid it by using symlink without “#” in it, or
- Not to write full path every time at all. In Mercurial we can define paths in hgrc (or .hgrc) and use them as alias.
Why I Think This # Is Ugly
Because the damned “-r” parameter exists, alive, and working that’s why.
Want to clone up to a revision? Type this:
$ hg clone -r 30 repopath newclone
Want to pull a revision from a remote repository? Type this:
$ hg pull -r c723c2da http://something.com/hg/
The reasoning why they have to treat “#” as revision identifier in a path is beyond me. Honestly I never use that feature and probably never will, I cannot think of a situation where this “feature” will be useful.