Mercurial
| The instructions provided in this article or section are considered advanced. You are expected to be knowledgeable in the UNIX shell. |
| The instructions provided in this article or section require shell access unless otherwise stated. You can use the PuTTY client on Windows, or SSH on UNIX and UNIX-like systems such as Linux or Mac OS X. |
Mercurial (official site) is a distributed version control system that is used track revisions of your files. You can find the unofficial manual here: (Distributed Revision Control with Mercurial).
Mercurial isn't currently installed by DreamHost (actually it appears that version 1.6.x is installed, skip to Configuration). This page will document how to install the latest version of Mercurial in your home account and get the webserver up and running. This is a work in progress.
Contents |
How To Install Mercurial
Updating instructions for Mercurial 1.7.5. --User:kylepoland 02/17/2011
- Note: These instructions assume everything works with no problems. If you have any issues, please make a note and we can try and get them fixed.
- Login to the shell account you would like to install Mercurial in
- Install python docutils package
easy_install docutils
If that doesn't work, edit your .bashrc to contain
export PYTHONPATH=~/lib/python2.5/site-packages
then reload the file
source .bashrc
Now you can use
$easy_install --prefix=~ docutils
- Download the latest Mercurial package (1.9.3 as of 04-Oct-2011)
mkdir -p ~/srcs cd ~/srcs wget http://mercurial.selenic.com/release/mercurial-1.7.5.tar.gz
- gunzip and untar the package
tar xvzf mercurial-[version].tar.gz
- Change directory to mercurial-[version]
cd mercurial-[version]
- Run the make all command
make all
- If you get an error at the end of the make that indicates
abort: couldn't generate documentation: docutils module is missingthen do a clean make and make local instead as shown next. This eliminates the need to edit the Makefile and remove references to the doc target.
- If you get an error at the end of the make that indicates
make clean make local
- Install the Mercurial package in your home directory. It will create bin, lib, and share directory in your home directory to install
make install-home
- If you had to run
make localabove, instead ofmake all, then you will need to run this instead
- If you had to run
make install-home-bin
- Assuming your are using bash shell, you need to update your PATH and PYTHONPATH environment variables to call this new local installation of mercurial instead of the old default version already installed on the system. You can do this by adding the updated env variables to your .bash_profile:
vi ~/.bash_profile
- add these lines at the bottom:
export PYTHONPATH=~/lib/python export PATH=~/bin:$PATH export HGRCPATH=~/.hgrc
- Now, do the same thing to your .bashrc (create one if it's not there already). Most methods of working with your repositories remotely issue non-interactive shells, and the .bash_profile will never be read. In general, this is likely to cause errors when mercurial attempts to run using the wrong set of python libraries. If the remote mercurial repository is running on the wrong python libraries, you will receive the somewhat unhelpful error
remote: abort: index 00changelog.i invalid format 2!
- update this shell process with the new variables:
source ~/.bash_profile
- Run the command hg --version and you should get the version information and copyright. Check that this version is the same as the version of the tar file you initially downloaded
hg --version
If you get Mercurial Distributed SCM (version unknown) for the version, remove the sources directory, expand from the tar again, and redo the make like so (tip from http://groups.google.com/group/mercurial_general/browse_thread/thread/ca8b6cabbee5eba3?tvc=2&fwc=2&pli=1):
cd ~/srcs rm -rf mercurial-1.7.5 tar xvzf mercurial-1.7.5.tar.gz cd mercurial-1.7.5 make local make install-home-bin
How to Configure a DreamHost Account to Serve a Mercurial Repository
- Note: These instructions are based on the instructions listed here ([1])
- Login to your shell account
- There needs to be a directory where the repository can be stored
mkdir -p ~/hg/repos
- Create the file hgweb.config
vi ~/hg/hgweb.config
- ...and add the following lines:
[collections] repos/ = repos/ [web] style = gitweb
- Copy the hgweb.cgi script to the hg directory
cp ~/srcs/mercurial-1.6.3/hgweb.cgi ~/hg chmod +x ~/hg/hgweb.cgi
- Check which python you have access to from dreamhost
which python python -V
- If you are not using 2.6.6 (as of 2012/07/07 this is the latest) then open the hgweb.cgi and update the sys path & the dir with python2.4
vi ~/hg/hgweb.cgi
Change the first line:
#!/usr/bin/env python
to:
#!/usr/bin/env python2.4
- Also change the two following lines:
config = "/path/to/repo/or/config" #import sys; sys.path.insert(0, "/path/to/python/lib")
to:
config = "/home/<user_name>/hg/hgweb.config" import sys; sys.path.insert(0, "/home/<user_name>/lib/python")
Note: <user_name> is your shell login name
- Create a .htaccess file for the hg directory (Taken from [2])
vi ~/hg/.htaccess
- ...add the following lines (Comments optional) and then save the file
# Taken from http://www.pmwiki.org/wiki/Cookbook/CleanUrls#samedir # Used at http://ggap.sf.net/hg/ Options +ExecCGI RewriteEngine On #write base depending on where the base url lives RewriteBase /hg RewriteRule ^$ hgweb.cgi [L] # Send requests for files that exist to those files. RewriteCond %{REQUEST_FILENAME} !-f # Send requests for directories that exist to those directories. RewriteCond %{REQUEST_FILENAME} !-d # Send requests to hgweb.cgi, appending the rest of url. RewriteRule (.*) hgweb.cgi/$1 [QSA,L]
- If you created your domain folder in your account to link directly to the ~/hg folder, then change the RewriteBase rule to:
RewriteBase /
- Create a symbolic link to the hg directory in your domain
cd to your domain directory ln -s ~/hg
- Test the directory - http://<your-domain.com>/hg
- You should see a web page that says "Mercurial Repositories"
- If you encounter errors check the server logs in /home/<user>/logs/<your-domain.com>/http.#####
- You may need to change the permissions within <your-domain.com>, see mercurial definitive guide.
chmod 755 ~ find ~/<your-domain.com> -type d -print0 | xargs -0r chmod 755 find ~/<your-domain.com> -type f -print0 | xargs -0r chmod 644
- RodW: I had to actually say chmod 500 hgweb.cgi in order to shut up suexec --Jceaser (talk) 10:04, 7 July 2012 (PDT): Confirm, still valid
- mikanboy: (May 3, 2011 / mercurial 1.7.5)If you get 'No module named shutil' error, check to make sure that you set the python path (in sys.path.insert) in hgweb.cgi correctly!!!
Create a New Repository
- Login to your shell account
- Create a repository called my_first_repo
hg init ~/hg/repos/my_first_repo
- Create a hgrc file for the repository
vi ~/hg/repos/my_first_repo/.hg/hgrc
- ...add the following lines to this file
[web] contact = <Your Name> description = My first Mercurial Repository push_ssl = false [ui] username = Firstname Lastname <youremailaddress@hostname.com>
- If you happen to need accents and/or tildes (áéíóú), also add to the [web] part:
charsets = utf-8
- Test your repository on DreamHost. First, make a file in your repository.
cd ~/hg/repos/my_first_repo date >> my_first_file hg add hg commit -m "Added my_first_file to the repository"
On your home system, try to clone your repository.
hg clone http://<your-domain>/hg/repos/my_first_repo local_repo_copy cat local_repo_copy/my_first_file
- By default, no one is allowed to push your repository. Read the next section, and review the Mercurial documentation on publishing repositories.
- If you want to share the access via SSH and not HTTP, skip the next section, the following one should have all the answers you need. The only thing you could need (if you want of course) is to restrict access by adding the lines to the .htaccess on the beginning of the next section. Everything after that (inside that section) has to do with http authentication.
Securing your Repositories
'This hasn't been updated since a while, so I don't know if it's actually working as of 1.6.3 --Pablo Olmos de Aguilera Corradini 22:55, 30 September 2010 (UTC)
- Login to your shell account
- Add this to the .htaccess file for the hg directory
AuthUserFile /home/<username>/hg/hgweb.passwd
AuthGroupFile /dev/null
AuthName "My Mercurial Repository"
AuthType Basic
<Limit GET POST PUT> # Remove GET to allow anonymous read-only access
Require valid-user
</Limit>
- Create hgweb.passwd
htpasswd -c -m ~/hg/hgweb.passwd <first-user> htpasswd -m ~/hg/hgweb.passwd <second-user> ...
- Set up user names in the repo hgrc
vi ~/hg/repos/my_first_repo/.hg/hgrc
- ...add the following line:
allow_push = <comma-delimited username list>
- "Trick" Mercurial into asking for authentication:
touch ~/hg/failed_auth.html
- You can avoid having to type in your user name and password each time by providing it when you clone the repository locally. If you did not clone the repository with a user name and password you can also update the .hg/hgrc of a local repository by updating the [paths] section.
hg clone http://<user>:<password>@<your-domain.com>/hg <localdir>
Sharing access to the repositories through SSH
I installed Mercurial 2.0 from source, and am only sharing the repository with myself. If this situation fits you there's no need to mess around with hg-ssh. You can just use your ssh key and change the remotecmd on client to point to the absolute path of your hg installation. For example, I compiled mercurial-2.0 from source per the earlier instructions and set up my remotecmd on TortoiseHg to be "~/bin/hg". This works for push / pull now. Example command line would be:
hg clone --verbose --debug ssh://<user>@<host>/<path-to-repo-relative-to-home-dir> --remotecmd "~/bin/hg"
I spent a lot of time tracking this issue down, since my non-interactive ssh would not load my .bash_profile or .bashrc and kept referencing the system wide 0.9.1 version of Mercurial. By specifying the absolute path to my Mercurial install I was able to pull and push successfully.
Thanks to Ry4an and mpm1 at #mercurial on irc.freenode.net for pointing me in this direction. --Karlgrz 15:27, 7 November 2011 (PST)
I haven't tested this for 1.6.3, I'll updated as soon as I do it. The file still exists and (I think) it's the same so this should work if you change the directory name. --Pablo Olmos de Aguilera Corradini 23:06, 30 September 2010 (UTC)
There are at least three ways to do this according to the Mercurial Wiki:
- Mercurial Server (Not the mercurial server, it's a piece of software that let's you configure your account to share the repository access with SSH)
- hg-ssh
- Hg-login
In this how-to I'm gonna use hg-ssh. It's the simplest way, but also the less sophisticated. Hg-login should work too, but I don't know why I couldn't make it work.
Be advised that this might be a not secure way and I have no doubt that should have many flaws, anyway I found it the most comfortable way since you don't have to send passwords in clear text through http. It could be a good idea to create a new user to just host the repositories so in the worst of the cases, someone could break in your repos and not your whole user directory.
Ok, let's get started:
- Login to your shell account
- Copy the hg-ssh script from the source to your bin directory
cp ~/srcs/mercurial-1.5.4/contrib/hg-ssh ~/bin
- Get the public ssh key of the people you want to have access to the Shared SSH (you can check the SSH Dreamhost Wiki instructions about Passwordless Login to achieve that
- Edit authorized_keys file to add hg-ssh so the collaborators can have only access through mercurial and no access to the shell
vim ~/.ssh/authorized_keys
- Before the previously added public keys add, but on the same line:
#So it will go from something like this: ssh-rsa [LONG STRING]== Collaborator1 #to: command="hg-ssh /home/username/hg/path/to/repo",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa [LONG STRING]== Collaborator1
- Supposedly it should work with a line break between ssh-rsa and the key itself...:
command="hg-ssh /home/username/hg/path/to/repo",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa
[LONG STRING]== Collaborator1
- ...but it didn't work for me
- Now you just have to use the ssh:// protocol. Even if to access via web you don't have to write repos, you have to write it down or the command will fail
hg clone ssh://<dreamhost-user-where-you-installed-mercurial>@domain.com/hg/repos/repo-name
Well, that's it. Remember though that this method doesn't allow advanced permissions like give only read access or just pull, but not push changes into the repository. Probably Hg-login can.
How to Configure a Dedicated Subdomain with Cleaner URLS
This section (not the following) doesn't work in 1.6.3 since those lines doesn't exist in hgweb.cgi --Pablo Olmos de Aguilera Corradini 23:02, 30 September 2010 (UTC)
The #import os line doesn't exists, but you can the needed code after the import sys;... line --Miquelfire 14:14, 1 October 2010 (UTC)
This step can be done after the previously listed steps, and should be done after having verified all other aspects are working
If your domain directory is one you have made explicitly for serving mercurial at the root level (e.g. something like http://hg.domain.com/some_repo), then you can do this by simply moving the .htaccess to your root public web directory (since it will rewrite to /hg/hgwebdir.cgi from root level, which is valid due to the ~/hg symlink):
cd to your domain directory mv ~/hg/.htaccess ./
- Now we make some modifications in hgwebdir.cgi:
vi ~/hg/hgwebdir.cgi
- Modify the following lines to override the script name (here I have given it a blank name so that nothing extra is prepended in links)
>Change this: #import os >to: import os # Force script name - needs webserver rewrite support os.environ["SCRIPT_NAME"] = ""
- Now you should be able to navigate projects with a format like http://hg.domain.com/some_repo instead of the existing format: http://hg.domain.com/hg/hgwebdir.cgi/some_repo
Delete (only) the hgwebdir.cgi in URL
If you are using a subdomain like http://hg.domain.com/hg/hgweb.cgi/some_repo and you just want to delete the annoying hgweb.cgi from the URL, but for some reason you want to keep the /hg:
- Don't move the .htaccess from /hg to the root folder
- Modify the hgweb.config:
vim ~/hg/hgweb.config
- Add below the [web] section the following:
baseurl = /hg
- So it will look something like this:
[collections] repos/ = repos/
[web] style = gitweb baseurl = /hg
- Now you should be able to see the projects in a format like http://hg.domain.com/hg/some_repo