Using Mercurial With SSH - hg: not found

Today I have started experimenting using Mercurial (hg) with ssh. Here are the two first pitfalls in which I have fallen.

As very well documented in the SSH section of the Distributed revision control with Mercurial, the first step is to set up your ssh configuration and make sure you can ssh to the server where the repository you want to access is located.

The easiest way to check that this is working is simply to ssh to the server. If you manage to log in, then check that you have hg in your PATH:

   $ ssh server-host
   $ hg version
   $ \^D

Then you need to check that everything still work in non interactive mode:

   $ ssh server-host hg version

The first pitfall

When I tried the second command above (ssh server-host hg version) I got the following error:

   dfuchs@server-host's password: 
   remote: ksh: hg:  not found
   abort: no suitable response from remote hg!

Since I had already verified that my PATH was correct on the remote server, my first idea was that for some reason my .profile (where I set my PATH variable) was not sourced when running ssh in non interactive mode. I quickly hacked my .profile to verify this (just added an echo "sourcing .profile" line in it), and bingo!
The file was not sourced.

A quick google search revealed that one way to fix this was to make my .kshrc source my .profile if my .profile hadn't been sourced already.

I modified my .profile to put a marker variable:

   PROFILE=yes;export PROFILE

and my .kshrc to source my .profile if the marker wasn't set:

   case "z$PROFILE" in
      z) # echo sourcing profile ; 
         . ~/.profile ;;
      z\*) # echo "profile already sourced" 

Tried ssh server-host hg version again, same result. This was obviously not working. Worse, it looked as if my .kshrc wasn't even sourced ever.

After reading my way through several internet searches and man pages such as

   man ssh 
   man sshd
   man sshd_config
   man ksh

I finally found a solution:

  • Create (or edit it if it already exists) a file named ~/.ssh/environment
  • and put this line inside:

This will make ssh export the ENV variable before calling ksh. In non interactive mode, ksh will source the file pointed to by the ENV variable. (see man ksh for more details).

   $ ssh server-host hg version
   dfuchs@server-host's password: 
   Mercurial Distributed SCM (version 0.9.3)


Update: On some systems, exporting ENV=~/.kshrc may not work: ksh will never source your ~/.kshrc or consult your ENV variable when invoked in non interactive mode through ssh. This may depend on the exact flavour of ssh/ksh that your system is using. In that case, you may want to reconsider your choice of login shell, and switch to bash. bash and ksh are mostly compatible - except from a few minor things, like the command print - which is a built-in equivalent to echo in ksh but doesn't exists in bash. I was able to switch painlessly from ksh to bash by simply adding:
type print 1> /dev/null 2> /dev/null
if [ $? -gt 0 ] ; then
   # define print if it does not exists
   print() {
     echo "$@"
at the beginning of the few of my ksh shell scripts that were using print.

The second pitfall

I fell in the second pitfall when I tried to do an hg clone. If you want to specify an absolute path when specifying the remote workspace in

   hg clone ssh://server-host<workspace-path> 

then <workspace-path> must begin with //, otherwise it's interpreted to be local to your home dir. so

   hg clone ssh://server-host/export/hg/repos

refers in fact to ~/export/hg/repos, while

   hg clone ssh://server-host//export/hg/repos

refers to /export/hg/repos. Again this is very well explained in the SSH section of the Distributed revision control with Mercurial.

Well of course all of this might not happen if your server machine has hg installed directly in /usr/bin...

Hope this help,
-- daniel


You got it all wrong! Shame on you. (hg works for me without problems).

Posted by Pedro on June 01, 2007 at 09:50 AM CEST #

Well, what shell are you using? I suspect my problems came from sticking to the old 'ksh'...

Posted by daniel on June 01, 2007 at 10:29 AM CEST #

Thanks. The second pitfall was exactly my issue. I've been digging for mercurial documentation and could find this. Thanks again.

Posted by guest on December 21, 2007 at 09:38 AM CET #

ssh://host//path/project needed for me as well, thanks. been searching for an hour.

Posted by guest on November 07, 2009 at 05:43 AM CET #

If you're switching from ksh, try zsh rather than bash. It's a superset of almost every shell, has lots of ksh specific emulation, is much more well behaved than bash when it comes to POSIX compliance or emulation, and has lots of nice interactive and programming features as well.

Posted by vsync on April 21, 2010 at 08:09 AM CEST #

Thanks for Pitfall#2.

Posted by Sebastian Weisgerber on June 27, 2010 at 05:12 PM CEST #


edit you ~/hgrc file
remotecmd =/java/devtools/sparc/mercurial/latest/bin/hg

and forget about ksh.

Posted by Dmitry Samersoff on July 08, 2010 at 08:24 AM CEST #

Thanks too! I also met the two problems, but first case was slightly different: I had configured my paths in .bash_profile and in non-interactive sh shell only the .bashrc file is sourced.

Posted by Al on July 23, 2010 at 02:27 AM CEST #

Needed to set 'PermitUnserEnvironment yes' in sshd_config to allow ~/.ssh/environment to work.

Posted by Brian Watt on February 09, 2012 at 12:10 AM CET #

Hello, thanks for the tips!

Here is the official docs about some of the issues/fixes one might encounter while using mercurial on a remote repo via ssh:

Posted by guest on March 10, 2013 at 07:55 PM CET #

Post a Comment:
Comments are closed for this entry.

Daniel Fuchs blogs on Scene Builder, JMX, SNMP, Java, etc...

The views expressed on this blog are those of the author and do not necessarily reflect the views of Oracle.


« January 2017